Mysql性能:总是卡住/慢的大查询

时间:2017-02-19 19:00:22

标签: mysql performance

我有以下查询,这总是使整个网站失败,因为等待表级锁定":

/*IPS\Patterns\_ActiveRecordIterator::count:246*/ SELECT SQL_CALC_FOUND_ROWS forums_posts . * , forums_topics . * 
FROM  `forums_posts` 
LEFT JOIN  `forums_topics` ON forums_posts.topic_id = forums_topics.tid
LEFT JOIN  `core_permission_index` ON core_permission_index.app =  'forums'
AND core_permission_index.perm_type =  'forum'
AND core_permission_index.perm_type_id = forums_topics.forum_id
LEFT JOIN  `forums_forums` ON forums_topics.forum_id = forums_forums.id
WHERE (
NULLIF( forums_topics.moved_to,  '' ) IS NULL
)
AND (
forums_forums.password IS NULL 
OR (
(
FIND_IN_SET( 2, forums_forums.password_override )
)
)
)
AND (
forums_forums.can_view_others =1
OR forums_topics.starter_id IS NULL
)
AND forums_forums.min_posts_view <=0
AND queued =0
AND forums_topics.approved =1
AND (
(
(
FIND_IN_SET( 2, perm_2 )
)
)
OR perm_2 =  '*'
)
ORDER BY post_date DESC 
LIMIT 185725 , 25

我有什么办法可以改善这个查询的性能而不是杀死进程/等待10分钟直到它完成?

2 个答案:

答案 0 :(得分:0)

如果这是一个“爬虫”,它正在给你的网站带来麻烦,你真的必须摆脱OFFSET的使用。或者获取一些过滤器以防止实际上是DOS(拒绝服务)攻击。至少告诉搜索机器人避开你的网站。 (这可能是一个简单的答案。)

让我们变得真实。 LIMIT 185725 , 25 - 那是第7429页。你真的穿过了那么多页吗?

你有什么行有这么多行,却没有方便的方法来“搜索”或“合并”数据?

其他问题:

OR代价高昂 - 它会阻止索引使用

LEFT JOIN经常需要查看“正确”的表格,但在没有任何内容时感到高兴。这可能比普通JOIN的性能更差。 (但是,业务逻辑可能需要它。)

由于查询的复杂性,SQL_CALC_FOUND_ROWS可能几乎与获取LIMIT的所有行一样长。注意搜索引擎过去常常说“大约180,000”的结果,然后就放弃了。也许你的应用也应该这样做。

肯定有一种更简单的方法NULLIF( forums_topics.moved_to, '' ) IS NULL

你在桌子上使用什么引擎?如果使用MyISAM,请切换到InnoDB;这可能会摆脱“桌面锁定”。

答案 1 :(得分:0)

请检查表类型是否为InnoDB。如果是MyISAM,请将其转换为InnoDB。当一些其他线程/查询正在更新该表中的任何行时,MyISAM无法读取表中的数据。它使用表级锁。

InnoDB使用MVCC在UPDATEs / INSERTs / DELETE更新表时启用SELECT。