使用临时的 MYSQL 优化;使用文件排序!!! -> 帮助
Posted
技术标签:
【中文标题】使用临时的 MYSQL 优化;使用文件排序!!! -> 帮助【英文标题】:MYSQL optimization for Using temporary; Using filesort!!! -> HELP 【发布时间】:2011-01-20 13:56:33 【问题描述】:伙计们,我正在尝试一段时间,但我无法优化 Using 临时;使用我的 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;
当我解释时......我明白了:
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)
我尝试了一些KEY,但没有结果:例如我为createdon和adid创建了一个索引,但mysql不会使用它。
这是我桌子的钥匙:
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)
这里是对表格的一些简要说明:
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)
任何帮助,我很感激!
【问题讨论】:
【参考方案1】: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
删除了不需要的连接并摆脱了不需要的GROUP BY
。
要摆脱filesort
,请创建以下索引:
CREATE INDEX ix_ads_e_v_created ON ads (enabled, verified, createdon)
【讨论】:
好的,改进了,但是...我还有一个小问题,现在查询正在扫描所有行【参考方案2】:您需要使用强制索引 - here you will find more information。但是,在您的情况下,它不会有太大帮助,因为您对连接和组使用不同的索引,因此 mysql 没有机会“重用”它们。
【讨论】:
【参考方案3】:好的,它有所改进,但现在查询正在扫描所有行: --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)
据我所知,我必须建立一个索引,对吗?但是在哪一列/列上?
【讨论】:
该查询没有扫描所有行:它使用具有ref
访问权限的索引并按索引顺序输出记录,而没有filesort
。另外,请更新您的原始问题,不要发布更新作为答案。谢谢。【参考方案4】:
只是为了笑……改成
SELECT STRAIGHT_JOIN(查询的其余部分)
通过使子类别表变小,优化器引擎将尝试使用它作为查询的基础,而不是查询中的第一个表...这个关键字“STRAIGHT_JOIN”在过去帮助我做 gov't查询 14+ 百万条记录加入 15+ 查找表,从 30+ 小时后挂起进程到不到 2 小时完成。
【讨论】:
以上是关于使用临时的 MYSQL 优化;使用文件排序!!! -> 帮助的主要内容,如果未能解决你的问题,请参考以下文章