- 问题形成:
使用SQL的in条件,查询上千条数据时,查询缓慢。
如,项目中一段sql:
select t.id from p_t_xl t where
<if test="idList != null and idList.size > 0">
t.id in
<foreach collection="idList" item="id" index="index" separator=","open="(" close=")">
#{id}
</foreach>
</if>
其中idList为程序中得到的包含上千条数据的集合,遍历效果为
select t.id from p_t_xl t where t.id in(?,?,?,?,?,?,?,?,?,?).
当数据很多时,查询速度缓慢。
- 寻求解法
使用with as 语句,为一个子查询语句块定义一个名称,使用该名称可以在查询语句的很多地方引用到这个子查询。
使用with as 子句,可以在比较复杂的查询中预先定义一个结果集,然后在查询中反复使用。with子查询只执行一次,将结果存储在临时表空间中。
with子句语法:
with temp_table1 as (select1),
temp_table2 as (select2),
temp_table3 as (select 3)
select * from table,temp_table1 where table.*** = temp_table1.***
不幸的是,MySQL并不支持with as用法。
WITH temp_table1 AS (SELECT id FROM p_t_xl)
[SQL]WITH temp_table1 AS (SELECT id FROM p_t_xl)
[Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'temp_table1 AS (SELECT id FROM p_t_xl)' at line 1
-使用exists
SELECT
t.id
FROM
p_t_xl t
WHERE
EXISTS(
SELECT a.id
FROM p_t_xl a
WHERE
a.id = t.id
)
- 总结
IN 要比EXISTS快, 如果查询的两个表大小相当,那么用in和exists差别不大。如果两个表中一个小表,一个是大表,则子查询表大的用exists,子查询表小的用in。
NOT EXISTS要比NOT IN 快,如果查询语句使用了not in 那么内外表都进行全表扫描,没有用到索引,而not extsts 的子查询依然能用到表上的索引。