酒店id查询常见问题及解决办法!(一)
优采云 发布时间: 2021-08-01 06:17酒店id查询常见问题及解决办法!(一)
后台优化内容组织,可作为开发规范1.SQL优化方面(1)存在并在
in 是外表和内表的哈希连接,而exists 是外表的一个循环循环,每次循环都会查询内表。说exists比in效率高是不准确的。如果要查询的两个表大小相同,in和exists的区别不大;如果两个表中的一个较小,另一个较大,则较大的子查询表使用存在,
In为小子查询表;
例如:A桌(小桌)、B桌(大桌)
select * from A where cc in(select cc from B) -->效率低,用到了A表上cc列的索引;
select * from A where exists(select cc from B where cc=A.cc) -->效率高,用到了B表上cc列的索引。
相反:
1 select * from B where cc in(select cc from A) -->效率高,用到了B表上cc列的索引
2 select * from B where exists(select cc from A where cc=B.cc) -->效率低,用到了A表上cc列的索引。
所以具体情况具体对待,我们项目中的多选查询条件一般都用在,因为查询条件一般不会太多,如果是子查询用的,比如出现在项目中,首先检查所有符合条件的房型ID,然后根据这些房型ID查询所有的酒店ID。这时候存在的使用效率比较高,反之亦然。
(2)not 存在且不在
如果查询语句中使用not in,则对内表和外表都进行全表扫描,不使用索引;并且不存在子查询仍然可以使用表上的索引。所以不管哪个表大,不存在总比不存在快。
我们在项目中并没有使用not in much,因为一般不是子查询,是固定值,没有条件就是有空的情况,而且值不多,所以我们经常直接写multiple和判断,如果查询条件太多,需要使用not exists
(3)where,条件中不需要空判断
尽量避免where子句中字段的空值判断,否则会导致引擎放弃使用索引而进行全表扫描,如:
select id from t where num is null
可以在num上设置默认值0,确保表中num列没有空值,然后这样查询:
select id from t where num=0
(4) 应该尽量避免在 where 子句中使用 or 来连接条件
尽量避免在where子句中使用or连接条件,否则会导致引擎放弃使用索引而进行全表扫描。切换到union后,性能有很大提升。
一段SQL写成这样:
select a.MemberID,a.MemberName,a.MemberPhone
from Member a,Member_Tmep b
where (a.MemberName = b.MemberName or a.MemberPhone = b.MemberPhone) and a.MemberID b.MemberID
改为如下:
--查询出会员姓名相同但ID不同的记录
select a.MemberID,a.MemberName,a.MemberPhone
from Member a
inner join Member_Tmep b on a.MemberName = b.MemberName and a.MemberID b.MemberID
union
--再查询出会员电话相同但ID不同的记录,进行合并
select a.MemberID,a.MemberName,a.MemberPhone
from Member a
inner join Member_Tmep b on a.MemberPhone = b.MemberPhone and a.MemberID b.MemberID
以这种方式再次执行,秒后执行完毕。
除上述情况外,还有一个常见的使用or语句的场景,即:查询某个字段的值等于几个特定值的记录。
例如,您需要查询成员名称为“张三”和“李思”的记录。我们可以这样写:
select * from Member where MemberName = '张三' or MemberName = '李四'
通常这种写法是没有问题的,但是在数据量很大的情况下,也会大大影响执行速度。
另一种写法是使用in语句,例如:
select * from Member where MemberName in ('张三','李四')
但是有人认为in语句也会引起全表扫描。尽量避免in和not in。
如果要查询的具体值是一个连续的数值范围,比如90-100,可以用bwteen...and语句代替。例如:
select * from Member where MemberID between 90 and 100
如果不能使用bwteen...and,还是需要使用union方法,比如:
select * from Member where MemberName = '张三'
union all
select * from Member where MemberName = '李四'
这里,因为名字是“张三”和“李斯”的成员不能有重复记录,所以可以用性能更高的union all代替union。
(5)应该尽量避免对where子句中的字段进行函数式操作,这会导致引擎放弃使用索引而进行全表扫描。例如:
<p>select id from t where substring(name,1,3)='abc'--name以abc开头的id
select id from t where datediff(day,createdate,'2005-11-30')=0--‘2005-11-30’生成的id
应改为:
select id from t where name like 'abc%'
select id from t where createdate>='2005-11-30' and createdate