今天晚上突然发现执行4条sql比执行1条还快,也就是说执行多条单条语句在一定条件下执行效率也是不错的。
4条sql语句如下:
customer
是生意关系表,store_id
和customer_id
都是店铺的id
,有索引。store
是店铺表,id是自增主键。我的数据库引擎是MyISAM
.
SELECT * FROM customer WHERE store_id=2 AND customer_id=8;
SELECT * FROM customer WHERE store_id=8 AND customer_id=2;
SELECT * FROM store WHERE id=2;
SELECT * FROM store WHERE id=8;
修改成1条sql语句
SELECT
COUNT(id)
FROM
store
WHERE id IN
(SELECT
customer_id
FROM
customer
WHERE (store_id = 2
AND customer_id = 8)
OR (store_id = 8
AND customer_id = 2)) ;
问题就出现了:执行四条语句需要
0.004s
,而执行下面的一条sql需要0.80s
,也就是说分别执行4条语句是执行一条语句的快了将近20
倍。
我的思考
然后我尝试把单条的sql语句拆成两条,先执行括号内的,发现只需要0.001s
,然后执行带in
的单条语句,也只需要0.001s
,为什么组合起来的时候会出现如此大的差距。然后我根据Profiler进行分析,发现Sending data
和executing
这两天占用时间比较长。
求证
是不是在某些条件下,多次执行简单sql语句效率确实比写一条复杂sql语句执行效率高,
上面为什么会出现这种情况,是不是sql语句的书写问题。请大神不吝指出,谢谢。
正常情況來說, sql 語句的邏輯越多執行肯定越慢, 相對一條條的執行. 不過也不盡然如此, 你多條語句執行就多一次 io 可能在大批量的查詢就導致性能比一次執行來的慢.
從你給出的一條語句查詢來看, 耗時因該都在 in 的操作中, in 會導致全表掃描, 效率相對較低
嘗試使用 join 來替代 in
select count(s.id) as c from store as s
right join (
select customer_id from customer
where (store_id=2 and customer_id=8)
or (store_id=8 and customer_id=2)
) as cj on s.id=cj.customer_id
MySQL的执行效率只和具体操作有关,和条数有毛线关系。
相同的操作,理论上也是一条语句更快,不用怀疑。
问题就在于这里的IN。
推荐使用Left Join来取代IN,会更有效率。
我直接解释你的思考那里吧:
先执行括号内的,store_id和customer_id都是有索引的,必然很快。
执行带IN的单条语句,数据库会解释成Where id=…… And id=…… And id=……的效果,还是会用到store里的索引。
组合起来为什么就变慢:
子查询的Select生成了一个类似临时表的东西,这里面是没有索引的!
貌似在某些数据库里,IN里面的子查询会在循环的时候执行多次?
不大清楚。。。
总之,尽量不要用IN就对了!