MySQL优化加入过滤和订单在不同的表上

时间:2016-02-28 06:53:23

标签: mysql

以下查询运行缓慢(超过五秒),每个表中有大约五百万条记录:

SELECT DISTINCT `items`.* 
FROM `items` 
INNER JOIN `tags` ON `tags`.`item_id` = `items`.`id` 
WHERE `tags`.`name` = '...'
ORDER BY `items`.`stars` DESC LIMIT 64;

我不清楚索引的最佳策略。我最初的想法是将复合索引添加到items.id + items.stars,将综合索引添加到tags.item_id + tags.name - 但这并没有显着缩短查询时间。我有所有外键的索引和items.starstags.name的索引。

EXPLAIN将我的索引(index_tags_on_item_id_and_nameindex_items_on_id_and_stars)显示为可能的密钥,但都未使用:

1 | SIMPLE | tags  | ref    | index_tags_on_name | 5 | const        | 326538 | Using where; Using temporary; Using filesort
2 | SIMPLE | items | eq_ref | PRIMARY            | 4 | tags.item_id | 1      |

关于如何以一方的标准和另一方的ORDER进行JOIN的任何想法或最佳实践?我现在唯一想到的是复制stars中的tags

2 个答案:

答案 0 :(得分:0)

如果您要仅选择一个表的列,为什么首先需要连接两个表?而是尝试像这样的子查询:

select * from items where id in ( select item_id from tags where tags.name = '...'
 ) order by items.stars desc limit 64

不确定它是否会改善性能,但值得尝试。

答案 1 :(得分:0)

您可以重新排列该查询以利用index(tags.item_id,tags.name)

SELECT DISTINCT `items`.* 
FROM `items` WHERE EXISTS
    (SELECT 1 FROM `tags` WHERE `tags`.`item_id` = `items`.`id` 
       AND `tags`.`name` = '...' ) 
ORDER BY `items`.`stars` DESC LIMIT 64;