我已经看到了一些涉及" 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-slow所示:
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-log
也许我的方法在这里错了?你会怎么做?感谢。
答案 0 :(得分:1)
几句话:
1)为什么要左右加入i / o(内部)加入? LEFT JOIN意味着您还希望获得与客户不匹配的记录,这是意图吗?如果没有,则JOIN i / o LEFT JOIN更快。
2)如果你只是这样做,为什么你需要加入:
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上做了一个复杂的条件,你似乎有索引,但它们没有被使用。这意味着这部分可能很慢。