2

我远离 SQL 大师,我正在尝试执行:

SELECT `apps`.* FROM `apps` 
 INNER JOIN `similars` 
 ON (`apps`.id = `similars`.similar_app_id OR `apps`.id = `similars`.app_id) 
WHERE (`similars`.app_id = 542 
 OR `similars`.similar_app_id = 542) 
 AND apps.id <> 542 
ORDER BY field(`similars`.app_id, 542) desc LIMIT 6

order by 比没有 order by 慢 20 倍。

explain extended 
SELECT DISTINCT `apps`.* 
  FROM `apps` 
  INNER JOIN `similars` 
    ON (`apps`.id = `similars`.similar_app_id 
    OR `apps`.id = `similars`.app_id) 
  WHERE (`similars`.app_id = 542 
    OR `similars`.similar_app_id = 542) AND apps.id <> 542 
  ORDER BY `similars`.app_id - 542 desc

给我 :

+----+-------------+----------+-------------+-- -------------------------------------------------- ------------+------------------------------------------------+- --------+------+--------+----------+--------------- -------------------------------------------------- ---------------------------------------------+
| 编号 | 选择类型 | 表| 类型 | 可能的键 | 关键 | key_len | 参考 | 行 | 过滤 | 额外 |
+----+-------------+----------+-------------+-- -------------------------------------------------- ------------+------------------------------------------------+- --------+------+--------+----------+--------------- -------------------------------------------------- ---------------------------------------------+
| 1 | 简单 | 相似| 索引合并 | index_app_id_and_similar_app_id,index_app_id,index_similar_app_id | index_app_id,index_similar_app_id | 5,5 | 空 | 241 | 100.00 | 使用 union(index_app_id,index_similar_app_id); 使用哪里;使用临时的;使用文件排序 |
| 1 | 简单 | 应用程序 | 范围 | 初级 | 初级 | 4 | 空 | 21493 | 100.00 | 使用哪里;使用连接缓冲区 |
+----+-------------+----------+-------------+-- -------------------------------------------------- ------------+------------------------------------------------+- --------+------+--------+----------+--------------- -------------------------------------------------- ---------------------------------------------+

我已经尝试了 app_id、similar_app_id 上的所有索引组合以及它们的组合。

任何提示或技巧?

谢谢

4

3 回答 3

0

无论LIMIT按未索引字段进行排序 - 在您的情况下,您对要排序的值进行计算总是需要更长的时间......

我会跳过扣除 542进行排序并为 app_id 添加索引

于 2011-03-21T02:03:53.383 回答
0

您可以尝试的一件事是将 WHERE 子句移到 JOIN 条件中。我认为mysql有时会在使用where子句过滤之前尝试进行连接。这只是你可以尝试的东西,我不确定它是否真的有帮助。

SELECT `apps`.* FROM `apps` 
 INNER JOIN `similars` 
 ON (`apps`.id = `similars`.similar_app_id OR `apps`.id = `similars`.app_id) 
  AND (
       (`similars`.app_id = 542 OR `similars`.similar_app_id = 542) 
       AND apps.id <> 542
  ) 
ORDER BY field(`similars`.app_id, 542) desc LIMIT 6
于 2011-03-21T02:09:18.580 回答
0

由于FIELD()正在调用一个函数,MySql 不能使用索引或排序,来自文档

在某些情况下,MySQL 无法使用索引来解析 ORDER BY... 您将 ORDER BY 与包含键列名称以外的术语的表达式一起使用

重写你ORDER BY的不使用任何函数,例如,如果你希望 aapp_id = 542出现在顶部,你可以这样写:

ORDER BY `similars`.app_id = 542 DESC
于 2011-03-21T04:20:30.973 回答