我一直有这个问题一段时间:https : //stackoverflow.com/questions/7770695/mysql-query-slow-until-reindex-column
看起来一切都很好,当我突然对表进行大量写入时,索引似乎死了,查询最多需要 2 秒。当我有很多流量时总是会发生这种情况,因此连锁反应几乎会使我的数据库服务器停机。
如果我重建索引,一切都会好起来的。什么可能导致索引中的这些突然“中断”?如何预防?
表定义:
+---------------+-----------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------+-----------------------+------+-----+---------+----------------+
| id | int(11) unsigned | NO | PRI | NULL | auto_increment |
| user_id | mediumint(8) unsigned | YES | MUL | NULL | |
| created | int(11) unsigned | YES | MUL | NULL | |
| track | int(11) unsigned | YES | MUL | NULL | |
| prop | int(11) unsigned | YES | MUL | NULL | |
| sequence | text | YES | | NULL | |
| location | varchar(255) | YES | | NULL | |
| type | tinyint(1) unsigned | YES | MUL | NULL | |
| flagged | int(11) unsigned | YES | MUL | 0 | |
| status | tinyint(1) unsigned | YES | MUL | 0 | |
| featured | tinyint(1) unsigned | YES | MUL | 0 | |
| recommended | tinyint(1) unsigned | YES | | 0 | |
| rendered | tinyint(1) unsigned | YES | | NULL | |
| fms_id | varchar(32) | YES | MUL | NULL | |
| comments | text | YES | | NULL | |
| tv | tinyint(1) unsigned | YES | | 0 | |
| performers | varchar(255) | YES | | NULL | |
| comp_34_votes | int(11) unsigned | YES | | 0 | |
| comp_35_votes | int(11) | YES | | 0 | |
| comp_36_votes | int(11) | YES | | 0 | |
+---------------+-----------------------+------+-----+---------+----------------+
Run Code Online (Sandbox Code Playgroud)
和突然变慢的查询(如果我删除 orderby 它并不慢):
SELECT sql_no_cache `p`.`id` as performance_id, `p`.`performers`, `t`.`name` as track_name, `p`.`location`, `p`.`fms_id`
FROM (`performances` p)
JOIN `tracks` t ON `p`.`track` = `t`.`id`
WHERE (p.status = 1 OR (p.status != 2 && p.flagged < 3))
AND `p`.`prop` IN ('1', '2', '3', '4', '5', '6', '8', '10', '11', '13')
AND `p`.`track` IN ('17', '9', '5', '15', '2', '3', '8', '6', '12', '4', '1')
AND `p`.`type` IN ('1', '0', '2')
ORDER BY `p`.`created` desc
LIMIT 11, 12
Run Code Online (Sandbox Code Playgroud)
和解释:
+----+-------------+-------+--------+--------------------------------+--------------+---------+--------------------------------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+--------+--------------------------------+--------------+---------+--------------------------------+------+-------------+
| 1 | SIMPLE | p | index | track,prop,flagged,status,type | created_desc | 5 | NULL | 45 | Using where |
| 1 | SIMPLE | t | eq_ref | PRIMARY | PRIMARY | 4 | db_123.p.track | 1 | Using where |
+----+-------------+-------+--------+--------------------------------+--------------+---------+--------------------------------+------+-------------+
Run Code Online (Sandbox Code Playgroud)
问题并不是真正的索引碎片。它与索引统计数据相关性更大。如果您使用 MyISAM,INSERT 的突然峰值会使 MySQL 查询优化器无法识别统计信息。这将导致 MySQL 查询优化器在 SELECT 查询的 EXPLAIN 计划中进行可怕的猜测。
如果你使用InnoDB,ANALYZE TABLE就变得完全没用了。
只要表相当小,ANALYZE TABLE您就可以为 MyISAM 做所有的事情了。定期重建索引可能会对 InnoDB 表有所帮助。
只要表不被大量写入,索引统计信息就会保持稳定,并且查询 EXPLAIN 计划将保持更加一致。
请记住:一旦您拥有大量INSERTs、UPDATEs、 和DELETEs,那么在下一次重建或 之前,所有值得信赖的索引统计数据的赌注都会被取消ANALYZE TABLE。
| 归档时间: |
|
| 查看次数: |
4980 次 |
| 最近记录: |