简体   繁体   English

MYSQL优化用于临时; 使用filesort !!! - >帮助

[英]MYSQL optimization for Using temporary; Using filesort!!! -> HELP

Guys I'm trying for some time now and I can't manage to optimize the Using temporary; 伙计我现在正在尝试一段时间,我无法优化使用临时; Using filesort from my EXPLAIN query. 使用我的EXPLAIN查询中的filesort。 OK so, I have this query: 好的,我有这个查询:

 SELECT a.adid, a.adtitle, a.addesc, scat.subcatname
FROM ads a
INNER JOIN cities ct ON a.cityid = ct.cityid
INNER JOIN subcats scat ON a.subcatid = scat.subcatid
INNER JOIN cats cat ON scat.catid = cat.catid
WHERE a.enabled = '1'
AND a.verified ='1'
GROUP BY a.adid
ORDER BY a.createdon DESC
LIMIT 16;

When I do EXPLAIN ... I get this: 当我做EXPLAIN时......我明白了:

    EXPLAIN SELECT a.adid, a.adtitle, a.addesc, scat.subcatname 
FROM ads a 
INNER JOIN cities ct ON a.cityid = ct.cityid 
INNER JOIN subcats scat ON a.subcatid = scat.subcatid 
INNER JOIN cats cat ON scat.catid = cat.catid 
WHERE a.enabled = '1' 
AND a.verified ='1' 
GROUP BY a.adid 
ORDER BY a.createdon DESC LIMIT 16;

+----+-------------+-------+--------+----------------------------------+----------+---------+--------------------------------+------+---------------------------------+
| id | select_type | table | type   | possible_keys                    | key      | key_len | ref                            | rows | Extra                           |
+----+-------------+-------+--------+----------------------------------+----------+---------+--------------------------------+------+---------------------------------+
|  1 | SIMPLE      | cat   | system | PRIMARY                          | NULL     | NULL    | NULL                           |    1 | Using temporary; Using filesort | 
|  1 | SIMPLE      | scat  | ref    | PRIMARY,catid                    | catid    | 2       | const                          |    7 |                                 | 
|  1 | SIMPLE      | a     | ref    | subcatid,cityid,verified,enabled | subcatid | 2       | bakecai_incontri.scat.subcatid |  954 | Using where                     | 
|  1 | SIMPLE      | ct    | eq_ref | PRIMARY                          | PRIMARY  | 2       | bakecai_incontri.a.cityid      |    1 | Using index                     | 
+----+-------------+-------+--------+----------------------------------+----------+---------+--------------------------------+------+---------------------------------+
4 rows in set (0.00 sec)

I have tried some KEY's but no result: for example I create an index for createdon and adid but mysql won't use it. 我尝试了一些KEY但没有结果:例如我为createdon和adid创建了一个索引,但mysql不会使用它。

Here are the keys for my table: 这是我桌子的钥匙:

SHOW INDEX FROM ads;

+-------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
|Table| Non_unique | Key_name           | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment |
+-------------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
| ads |          0 | PRIMARY            |            1 | adid        | A         |        8592 |     NULL | NULL   |      | BTREE      |         | 
| ads |          1 | subcatid           |            1 | subcatid    | A         |           9 |     NULL | NULL   |      | BTREE      |         | 
| ads |          1 | cityid             |            1 | cityid      | A         |         103 |     NULL | NULL   |      | BTREE      |         | 
| ads |          1 | verified           |            1 | verified    | A         |           2 |     NULL | NULL   | YES  | BTREE      |         | 
| ads |          1 | enabled            |            1 | enabled     | A         |           2 |     NULL | NULL   | YES  | BTREE      |         | 
| ads |          1 | idx_createdon_adid |            1 | createdon   | A         |        8592 |     NULL | NULL   |      | BTREE      |         | 
| ads |          1 | idx_createdon_adid |            2 | adid        | A         |        8592 |     NULL | NULL   |      | BTREE      |         | 
| ads |          1 | srch_text          |            1 | adtitle     | NULL      |           1 |     NULL | NULL   | YES  | FULLTEXT   |         | 
| ads |          1 | srch_text          |            2 | addesc      | NULL      |           1 |     NULL | NULL   | YES  | FULLTEXT   |         | 
| ads |          1 | srch_text          |            3 | nome        | NULL      |           1 |     NULL | NULL   | YES  | FULLTEXT   |         | 
+-------------+------------+--------------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+
10 rows in set (0.00 sec)

HERE are some brief description of the tables: 这里有一些表的简要说明:

 DESCRIBE ads
    -> ;
+-----------+----------------------+------+-----+---------------------+----------------+
| Field     | Type                 | Null | Key | Default             | Extra          |
+-----------+----------------------+------+-----+---------------------+----------------+
| adid      | int(10) unsigned     | NO   | PRI | NULL                | auto_increment | 
| nome      | varchar(255)         | YES  |     | NULL                |                | 
| eta       | varchar(255)         | YES  |     | NULL                |                | 
| adtitle   | varchar(100)         | YES  | MUL | NULL                |                | 
| addesc    | text                 | YES  |     | NULL                |                | 
| email     | varchar(50)          | YES  |     | NULL                |                | 
| phone     | varchar(255)         | YES  |     | NULL                |                | 
| showemail | enum('0','1','2')    | YES  |     | NULL                |                | 
| code      | varchar(35)          | YES  |     | NULL                |                | 
| first     | varchar(255)         | YES  |     | NULL                |                | 
| cityid    | smallint(5) unsigned | NO   | MUL | 0                   |                | 
| subcatid  | smallint(5) unsigned | NO   | MUL | 0                   |                | 
| price     | decimal(10,2)        | NO   |     | 0.00                |                | 
| hits      | int(10) unsigned     | NO   |     | 0                   |                | 
| ip        | varchar(15)          | YES  |     | NULL                |                | 
| link      | varchar(255)         | YES  |     | http://             |                | 
| verified  | enum('0','1')        | YES  | MUL | NULL                |                | 
| abused    | int(10) unsigned     | NO   |     | 0                   |                | 
| enabled   | enum('0','1')        | YES  | MUL | NULL                |                | 
| createdon | datetime             | NO   | MUL | 0000-00-00 00:00:00 |                | 
| expireson | datetime             | NO   |     | 0000-00-00 00:00:00 |                | 
| timestamp | timestamp            | NO   |     | CURRENT_TIMESTAMP   |                | 
+-----------+----------------------+------+-----+---------------------+----------------+
22 rows in set (0.02 sec)

DESCRIBE cities
    -> ;
+-----------+----------------------+------+-----+-------------------+----------------+
| Field     | Type                 | Null | Key | Default           | Extra          |
+-----------+----------------------+------+-----+-------------------+----------------+
| cityid    | smallint(5) unsigned | NO   | PRI | NULL              | auto_increment | 
| cityname  | varchar(50)          | YES  |     | NULL              |                | 
| regionid  | smallint(5) unsigned | NO   | MUL | 0                 |                | 
| pos       | smallint(5) unsigned | NO   | MUL | 0                 |                | 
| enabled   | enum('0','1')        | YES  | MUL | NULL              |                | 
| timestamp | timestamp            | NO   |     | CURRENT_TIMESTAMP |                | 
+-----------+----------------------+------+-----+-------------------+----------------+
6 rows in set (0.00 sec)

DESCRIBE cats
    -> ;
+-----------+----------------------+------+-----+-------------------+----------------+
| Field     | Type                 | Null | Key | Default           | Extra          |
+-----------+----------------------+------+-----+-------------------+----------------+
| catid     | smallint(5) unsigned | NO   | PRI | NULL              | auto_increment | 
| catname   | varchar(50)          | YES  |     | NULL              |                | 
| pos       | smallint(5) unsigned | NO   |     | 0                 |                | 
| enabled   | enum('0','1')        | YES  | MUL | NULL              |                | 
| timestamp | timestamp            | NO   |     | CURRENT_TIMESTAMP |                | 
+-----------+----------------------+------+-----+-------------------+----------------+
5 rows in set (0.00 sec)

Any help , i appreciate! 任何帮助,我很感激!

SELECT  a.adid, a.adtitle, a.addesc, scat.subcatname
FROM    ads a
INNER JOIN
        subcats scat
ON      a.subcatid = scat.subcatid
WHERE   a.enabled = '1'
        AND a.verified ='1'
ORDER BY a.createdon
        DESC
LIMIT 16

Removed unneeded joins and got rid of unneeded GROUP BY . 删除了不需要的连接并删除了不需要的GROUP BY

To get rid of filesort , create the following index: 要删除filesort ,请创建以下索引:

CREATE INDEX ix_ads_e_v_created ON ads (enabled, verified, createdon)

You need to play around with forcing indices - here you will find more information . 您需要使用强制索引 - 在这里您可以找到更多信息 However in you case it won't help much, because you use different indices for joins and for groups so mysql has no chance to "reuse" them. 但是在你的情况下它没有多大帮助,因为你为连接和组使用不同的索引,所以mysql没有机会“重用”它们。

OK, it improved but now the query is scanning all the rows: --hmm i think this is because all of the lines have enabled and verified equal to 1... 好的,它改进但现在查询扫描所有行: - hmm我认为这是因为所有行已启用并验证等于1 ...

EXPLAIN SELECT a.adid, a.adtitle, a.addesc, scat.subcatname
    -> FROM ads a
    -> INNER JOIN subcats scat 
    -> ON a.subcatid = scat.subcatid
    -> WHERE a.enabled = '1'
    -> AND a.verified ='1'
    -> ORDER BY a.createdon DESC
    -> LIMIT 16;
+----+-------------+-------+--------+----------------------------------------------+--------------------+---------+-----------------------------+------+-------------+
| id | select_type | table | type   | possible_keys                                | key                | key_len | ref                         | rows | Extra       |
+----+-------------+-------+--------+----------------------------------------------+--------------------+---------+-----------------------------+------+-------------+
|  1 | SIMPLE      | a     | ref    | subcatid,verified,enabled,ix_ads_e_v_created | ix_ads_e_v_created | 4       | const,const                 | 8485 | Using where | 
|  1 | SIMPLE      | scat  | eq_ref | PRIMARY                                      | PRIMARY            | 2       | bakecai_incontri.a.subcatid |    1 |             | 
+----+-------------+-------+--------+----------------------------------------------+--------------------+---------+-----------------------------+------+-------------+
2 rows in set (0.00 sec)

From what I know I have to make an index right? 据我所知,我必须做一个正确的指数? but on wich column/columns? 但是哪一列/列?

Just for grins... change to 只是为了笑容......改变

SELECT STRAIGHT_JOIN (rest of your query) SELECT STRAIGHT_JOIN(您的查询的其余部分)

By having the subcategory table being small, the optimizer engine will try to use that as basis of querying and NOT the first table in the query... This one keyword "STRAIGHT_JOIN" has helped me in the past doing gov't queries of 14+ million records joined to 15+ lookup tables from hanging the process after 30+ hours to less than 2 hours to complete. 通过使子类别表小,优化器引擎将尝试使用它作为查询的基础而不是查询中的第一个表...这个关键字“STRAIGHT_JOIN”在过去帮助我做了14个gov't查询从30多个小时到完成不到2个小时的过程,将超过100个记录加入到15个以上的查找表中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM