Mysql 优化连接查询
我在下面的查询中遇到了问题,在按kp_vowers DESC、kp_rating DESC添加ORDER之后,它变得非常慢,问题是我已经为这些列创建了索引Mysql 优化连接查询,mysql,sql,Mysql,Sql,我在下面的查询中遇到了问题,在按kp_vowers DESC、kp_rating DESC添加ORDER之后,它变得非常慢,问题是我已经为这些列创建了索引 explain SELECT * FROM post JOIN post_plus ON post_plus.news_id = post.id WHERE category regexp '[[:<:]](131|138|139|140|141|14
explain SELECT *
FROM post
JOIN post_plus
ON post_plus.news_id = post.id
WHERE category regexp '[[:<:]](131|138|139|140|141|142|143|144|145|146|147|148|149|150|151|152|153|154|155|156|157|171|172|134|136|137|23|123)[[:>:]]'
AND approve=1
AND allow_main=1
ORDER BY kp_votes DESC,
kp_rating DESC LIMIT 30;
+----+-------------+---------------+------+--------------------------------------+------------+---------+--------------------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+---------------+------+--------------------------------------+------------+---------+--------------------+-------+----------------------------------------------+
| 1 | SIMPLE | post | ref | PRIMARY,allow_main,approve,approve_2 | allow_main | 1 | const | 12273 | Using where; Using temporary; Using filesort |
| 1 | SIMPLE | post_plus | ref | news_id | news_id | 5 | online.post.id | 1 | NULL |
+----+-------------+---------------+------+--------------------------------------+------------+---------+--------------------+-------+----------------------------------------------+
另一个命令工作得很快。。。例如,如果我按fixed desc、date desc LIMIT 30设置订单,它的执行速度将提高10倍
描述职位
+------------------+-----------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+-----------------------+------+-----+---------------------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| autor | varchar(40) | NO | MUL | | |
| date | datetime | NO | MUL | 0000-00-00 00:00:00 | |
| full_story | text | NO | MUL | NULL | |
| xfields | text | NO | | NULL | |
| title | varchar(255) | NO | MUL | | |
| descr | varchar(200) | NO | MUL | | |
| keywords | text | NO | | NULL | |
| category | varchar(200) | NO | MUL | 0 | |
| alt_name | varchar(200) | NO | MUL | | |
| comm_num | mediumint(8) unsigned | NO | MUL | 0 | |
| allow_comm | tinyint(1) | NO | | 1 | |
| allow_main | tinyint(1) unsigned | NO | MUL | 1 | |
| approve | tinyint(1) | NO | MUL | 0 | |
| fixed | tinyint(1) | NO | | 0 | |
| allow_br | tinyint(1) | NO | | 1 | |
| symbol | varchar(3) | NO | MUL | | |
| tags | varchar(255) | NO | MUL | | |
| metatitle | varchar(255) | NO | | | |
| FileTempUUID | varchar(11) | YES | | NULL | |
| titleAlternative | varchar(255) | YES | | NULL | |
+------------------+-----------------------+------+-----+---------------------+----------------+
21 rows in set (0.01 sec)
mysql>描述post_plus
+-----------+------------+------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-----------+------------+------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| post_plus | 0 | PRIMARY | 1 | pid | A | 32317 | NULL | NULL | | BTREE | | |
| post_plus | 1 | user_id | 1 | user_id | A | 26 | NULL | NULL | | BTREE | | |
| post_plus | 1 | news_id | 1 | news_id | A | 32317 | NULL | NULL | YES | BTREE | | |
| post_plus | 1 | kp_votes | 1 | kp_votes | A | 4616 | NULL | NULL | YES | BTREE | | |
| post_plus | 1 | kp_rating | 1 | kp_rating | A | 5386 | NULL | NULL | YES | BTREE | | |
| post_plus | 1 | kp_id | 1 | kp_id | A | 16158 | NULL | NULL | YES | BTREE | | |
| post_plus | 1 | post_uuid | 1 | post_uuid | A | 32317 | NULL | NULL | YES | BTREE | | |
| post_plus | 1 | blockedCountries | 1 | blockedCountries | A | 10 | NULL | NULL | YES | BTREE | | |
| post_plus | 1 | kp_votes_2 | 1 | kp_votes | A | 5386 | NULL | NULL | YES | BTREE | | |
+---------------+------------+------------------+--------------+------------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
+------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+----------------+
| pid | int(11) | NO | PRI | NULL | auto_increment |
| news_id | int(11) | YES | MUL | NULL | |
| kp_votes | int(11) | YES | MUL | NULL | |
| kp_rating | decimal(5,3) | YES | MUL | NULL | |
| kp_id | varchar(100) | YES | MUL | NULL | |
| pdate | datetime | YES | | NULL | |
| news_read | int(11) | NO | | 0 | |
| user_id | int(11) | NO | MUL | 0 | |
| allow_rate | tinyint(1) | NO | | 1 | |
| rating | mediumint(8) | NO | | 0 | |
| vote_num | mediumint(8) | NO | | 0 | |
| votes | tinyint(1) | NO | | 0 | |
| editdate | int(11) | YES | | NULL | |
| view_edit | tinyint(1) | NO | | 0 | |
| editor | varchar(40) | NO | | | |
| reason | varchar(255) | NO | | | |
| access | varchar(150) | NO | | | |
| cover | text | YES | | NULL | |
| quality | varchar(100) | YES | | NULL | |
| post_uuid | varchar(11) | YES | MUL | NULL | |
| encoded | int(1) | YES | | NULL | |
| embed_views | int(11) | NO | | 0 | |
| blockedCountries | varchar(128) | YES | MUL | NULL | |
+------------------+--------------+------+-----+---------+----------------+
25 rows in set (0.00 sec)
编辑*
我试着加上:
on post (approve, allow_main, category) (depending on the cardinality it can be different order) and use category IN () because that can take advantage of good indexes while regexp can't.
on post_plus (news_id, kp_votes, kp_rating) (order matters here) that will help with the sorting
正如卡罗利·纳吉(Károly Nagy)所建议的那样,但没有起到任何作用。mysql拒绝使用kp_投票和kp_评级索引。您可以在
如果类别为1311381391401411421431441451461471491195015115215315415515617171172134136137,23123,在没有看到实际数据的情况下,我只能告诉以下几点: 结果集相当大,表缺少适当的索引。正如我看到的,您使用的是单列索引,而不是更适合查询的复合索引。news_id索引用于连接表,因此即使您在kp_*列上有索引,也不能使用它们 这里您需要的是两个compozite索引: 在post approve上,allow_main,category根据基数的不同,它可以是不同的顺序,并在中使用category,因为这样可以利用好的索引,而regexp不能。 在post_plus news_id、kp_投票中,kp_评级顺序将有助于排序
ps:您可能需要帮助MySQL按照什么顺序加入。请参阅添加索引后的解释,如果看起来不太好,请尝试直接加入您能提供一个数据的示例吗?并添加表别名,以明确哪些列来自哪些表。选择*而不是只选择所需的字段总是会降低速度。@Dan:当然你是对的。最好只传输您需要的数据。但这并不能解释添加orderby…后的性能差异。。。。我的猜测是,结果集很大,现在必须在返回前30行之前对其进行排序。所以有一个问题:有多少行没有限制?选择计数*会告诉你。但这不是问题所在。。。正如我提到的,如果没有顺序,它的执行速度要快10倍。添加索引和直接连接没有帮助。它只是不使用这些索引…您能创建模式并在SQLFIDLE上放入一些测试数据吗?那我可以仔细看看。