2013-07-19 123 views
-1

我有一个复杂的查询,它产生我想要的结果,非常缓慢。 (!像600秒)MySQL中的索引相关子查询

SELECT * 
FROM clients 
WHERE type = 'gold' 
     AND state IN('TX', 'WV', 'NV', 'IL') 
AND phone not in 
     (
      select phone 
      from clients 
      group by phone 
      having count(*) > 1 
     ) 
AND cell not in 
     (
      select cell 
      from clients 
      group by cell 
      having count(*) > 1 
     ) 

EXPLAIN SELECT给我:

id, select_type, table, Possible_keys, key, key_len, ref, rows, Extra 
1, PRIMARY, clients, ALL, ndxCLients_state,IGA_Count, , , , 128070, Using where 
2, DEPENDENT SUBQUERY, clients, ALL, , , , , 128070, Using temporary; Using filesort 
3, DEPENDENT SUBQUERY, clients, index, , idx_Cell, 258, , 3, Using index 

我与这里做什么挣扎。我认为它试图告诉我,我需要在电话领域的索引。我使用mysql工作台索引了手机领域。我在这里错过了什么?

+0

**您需要向我们展示表和索引定义。**诊断慢查询需要全表和索引定义,而不仅仅是描述或释义。也许你的表格定义不好。也许索引没有正确创建。也许你没有一个你认为你做过的那个专栏的索引。没有看到表和索引定义,我们不能说。 –

+0

谢谢安迪。我担心这一点。我不得不提出一个修剪和紧凑的版本,因为我正在学习一个巨大的丑陋生产数据库。 – JVMX

+0

使用https://www.sqlfiddle.com并将小数据集放在客户端表中。 – amaster

回答

0

使用LEFT JOIN往往优于INNOT IN

SELECT c.* 
FROM clients c 
LEFT JOIN (SELECT phone 
      FROM clients 
      GROUP BY phone 
      HAVING COUNT(*) > 1) p 
ON c.phone = p.phone 
LEFT JOIN (SELECT cell 
      FROM clients 
      GROUP BY cell 
      HAVING COUNT(*) > 1) cl 
ON c.cell = p.cell 
WHERE p.phone IS NULL AND cl.cell IS NULL 
AND type = 'gold' 
AND state IN('TX', 'WV', 'NV', 'IL') 

确保您有phonecell指标。它们可能会或可能不会用于JOIN,具体取决于type和/或state上的索引是否更有用,但是它们将用于优化子查询中的GROUP BY