2014-06-05 53 views
2

我在MySQL查询中看到了一些涉及“NOT IN”效率低下的问题,但我没有设法重现所提出的解决方案。使用“NOT IN”优化MySQL查询

所以我有某种搜索引擎。它从非常简单的查询开始,然后尝试更复杂的查询,如果找不到足够的结果。这是伪代码如何工作

list_of_ids = do_simple_search() 
nb_results = size_of(list_of_ids) 

if nb_results < max_nb_results : 
    list_of_ids .= do_search_where_id_not_in(list_of_ids) 

    if nb_results < max_nb_results : 
     list_of_ids .= do_complicated_search_where_id_not_in(list_of_ids) 

希望我很清楚。 反正这里的慢查询,如由MySQL慢:

SELECT DISTINCT c.id 
FROM clients c LEFT JOIN communications co ON c.id = co.client_id 
WHERE (co.titre LIKE 'S' OR co.contenu LIKE 'S') AND c.id NOT IN(N) 
LIMIT N, N 

,这里是一个对查询说明:

id select_type  table type possible_keys    key   key_len ref    rows Extra 
1 SIMPLE   c  index PRIMARY      PRIMARY  2  NULL   25250 Using where; Using index; Using temporary 
1 SIMPLE   co  ref  qui_com,id_client,titre  id_client 2  klients.c.id 8  Using where; Distinct 

MySQL版本是5.1.63-0ubuntu0.11.04.1日志

也许我的方法在这里是错的?你会怎么做?谢谢。

+0

你有性能问题吗? – serakfalcon

+1

如果您希望我们帮助优化查询,您需要向我们显示表格和索引定义**以及每个表格的行数。也许你的表格定义不好。也许索引没有正确创建。也许你没有一个你认为你做过的那个专栏的索引。没有看到表和索引定义,我们不能说。我们还需要行计数,因为这会大大影响查询优化。如果你知道如何做一个'EXPLAIN'或者得到一个执行计划,那就把结果也放在问题中。如果您没有索引,请尽快访问http://use-the-index-luke.com。 –

+0

非常感谢您的支持,我会尽力找出自己的想法,然后回来 – Bootdisk

回答

1

一对夫妇的言论:

1)你为什么这样做LEFT JOIN I/O(内连接)? LEFT JOIN意味着你还想获得不匹配客户的记录,这是用意吗?如果不是,则JOIN I/O LEFT JOIN更快。

2)为什么你需要JOIN在所有如果你可以简单地做:

SELECT DISTINCT co.client_id from communications co 
WHERE (co.titre LIKE 'S' OR co.contenu LIKE 'S') AND co.id!=N LIMIT N,N; 

此外,如果你做一个JOIN,双双加盟字段必须是索引,否则它的速度慢了。

更重要的是,你同时处理了通信表中的client_id和id,但是这两者都没有共同的索引,这意味着更多的工作来执行你的查询(因此using temporary这通常不是一个好兆头)。

3)你对co.titre和co.contenu都做了一个复杂的条件,你似乎有索引但是没有被使用。这意味着这部分可能会很慢。

+0

哦,哇,我不敢相信我忽视了我不需要那种加入。非常感谢,这确实更简单。 – Bootdisk

+0

不客气:) – Ashalynd

+1

该死的,我只是意识到为什么我必须做JOIN。在某些情况下,我也在检查客户的状态。 所以你建议我用JOIN替换我的LEFT JOIN。 SQL从来就不是我最强烈的观点:/ – Bootdisk