MySQL索引减慢了查询速度 [英] MySQL index slowing down query

查看:116
本文介绍了MySQL索引减慢了查询速度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

MySQL Server version: 5.0.95
Tables All: InnoDB

我遇到了MySQL数据库查询的问题。基本上我发现如果我索引一个特定的varchar(50)字段 tag.name ,我的查询需要更长的时间(x10)而不是索引字段。我试图加快这个问题,但是我的努力似乎反效果。

I am having an issue with a MySQL db query. Basically I am finding that if I index a particular varchar(50) field tag.name, my queries take longer (x10) than not indexing the field. I am trying to speed this query up, however my efforts seem to be counter productive.

罪魁祸首的行和字段似乎是:

The culprit line and field seems to be:

WHERE `t`.`name` IN ('news','home')

我注意到如果我直接查询标签表没有使用相同条件的连接,并且索引名称字段,我没有问题..它实际上工作得更快。

I have noticed that if i query the tag table directly without a join using the same criteria and with the name field indexed, i do not have the issue.. It actually works faster as expected.

示例查询**

EXAMPLE Query **

      SELECT `a`.*, `u`.`pen_name`
        FROM `tag_link` `tl`
  INNER JOIN `tag` `t`
          ON `t`.`tag_id` = `tl`.`tag_id`
  INNER JOIN `article` `a` 
          ON `a`.`article_id` = `tl`.`link_id`
  INNER JOIN `user` `u`
          ON `a`.`user_id` = `u`.`user_id`   
       WHERE `t`.`name` IN ('news','home')
         AND `tl`.`type` = 'article'
         AND `a`.`featured` = 'featured'
    GROUP BY `article_id`
       LIMIT 0 , 5

EXPLAIN with index **

EXPLAIN with index **

| id | select_type | table | type   | possible_keys            | key     | key_len | ref               | rows | Extra                                                     |
+----+-------------+-------+--------+--------------------------+---------+---------+-------------------+------+-----------------------------------------------------------+
|  1 | SIMPLE      | t     | range  | PRIMARY,name             | name    | 152     | NULL              |    4 | Using where; Using index; Using temporary; Using filesort | 
|  1 | SIMPLE      | tl    | ref    | tag_id,link_id,link_id_2 | tag_id  | 4       | portal.t.tag_id   |   10 | Using where                                               | 
|  1 | SIMPLE      | a     | eq_ref | PRIMARY,fk_article_user1 | PRIMARY | 4       | portal.tl.link_id |    1 | Using where                                               | 
|  1 | SIMPLE      | u     | eq_ref | PRIMARY                  | PRIMARY | 4       | portal.a.user_id  |    1 |                                                           | 
+----+-------------+-------+--------+--------------------------+---------+---------+-------------------+------+-----------------------------------------------------------+

没有索引的EXPLAIN **

EXPLAIN without index **

+----+-------------+-------+--------+--------------------------+---------+---------+---------------------+------+-------------+
| id | select_type | table | type   | possible_keys            | key     | key_len | ref                 | rows | Extra       |
+----+-------------+-------+--------+--------------------------+---------+---------+---------------------+------+-------------+
|  1 | SIMPLE      | a     | index  | PRIMARY,fk_article_user1 | PRIMARY | 4       | NULL                | 8742 | Using where | 
|  1 | SIMPLE      | u     | eq_ref | PRIMARY                  | PRIMARY | 4       | portal.a.user_id    |    1 |             | 
|  1 | SIMPLE      | tl    | ref    | tag_id,link_id,link_id_2 | link_id | 4       | portal.a.article_id |    3 | Using where | 
|  1 | SIMPLE      | t     | eq_ref | PRIMARY                  | PRIMARY | 4       | portal.tl.tag_id    |    1 | Using where | 
+----+-------------+-------+--------+--------------------------+---------+---------+---------------------+------+-------------+

TABLE CREATE

CREATE TABLE `tag` (
  `tag_id` int(11) NOT NULL auto_increment,
  `name` varchar(50) NOT NULL,
  `type` enum('layout','image') NOT NULL,
  `create_dttm` datetime default NULL,
  PRIMARY KEY  (`tag_id`)
) ENGINE=InnoDB AUTO_INCREMENT=43077 DEFAULT CHARSET=utf8 

INDEXS

SHOW INDEX FROM tag_link;
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table    | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| tag_link |          0 | PRIMARY  |            1 | tag_link_id | A         |       42023 |     NULL | NULL   |      | BTREE      |         |
| tag_link |          1 | tag_id   |            1 | tag_id      | A         |       10505 |     NULL | NULL   |      | BTREE      |         |
| tag_link |          1 | link_id  |            1 | link_id     | A         |       14007 |     NULL | NULL   |      | BTREE      |         |
+----------+------------+----------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+

SHOW INDEX FROM article;
+---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| Table   | Non_unique | Key_name         | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| article |          0 | PRIMARY          |            1 | article_id  | A         |        5723 |     NULL | NULL   |      | BTREE      |         |
| article |          1 | fk_article_user1 |            1 | user_id     | A         |           1 |     NULL | NULL   |      | BTREE      |         |
| article |          1 | create_dttm      |            1 | create_dttm | A         |        5723 |     NULL | NULL   | YES  | BTREE      |         |
+---------+------------+------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+

最终解决方案
似乎MySQL只是不正确地排序数据。最后,将标签表看作返回id的子查询更快。

Final Solution It seems that MySQL is just sorted the data incorrectly. In the end it turned out faster to look at the tag table as a sub query returning the ids.

推荐答案

你有多大表?
我在第一个解释中注意到你有一个使用临时;使用filesort这是不好的。您的查询很可能被转储到光盘,这使得它比内存查询慢。
也尽量避免使用select *而是查询所需的最小字段。

How big are your tables? I noticed in the first explain you have a "Using temporary; Using filesort" which is bad. Your query is likely being dumped to disc which makes it way slower than in memory queries. Also try to avoid using "select *" and instead query the minimum fields needed.

这篇关于MySQL索引减慢了查询速度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆