【发布时间】:2011-03-24 23:51:51
【问题描述】:
我有一个带有嵌套索引(blog_id,published)的 mysql 表(文章),并且性能很差。我在我的慢查询日志中看到了很多这样的情况:
- Query_time: 23.184007 Lock_time: 0.000063 Rows_sent: 380 Rows_examined: 6341
SELECT id from articles WHERE category_id = 11 AND blog_id IN (13,14,15,16,17,18,19,20,21,22,23,24,26,27,6330,6331,8269,12218,18889) order by published DESC LIMIT 380;
我很难理解为什么 mysql 会使用这些 blog_id 遍历 all 行来找出我的前 380 行。我希望嵌套索引的全部目的是加快速度。至少,即使是一个幼稚的实现,也应该通过 blog_id 查找并获得按已发布排序的前 380 行。这应该很快,因为由于嵌套索引,我们可以计算出准确的 200 行。然后对生成的 19*200=3800 行进行排序。
如果要以最佳方式实现它,您将从所有基于 blog-id 的流的集合中放置一个堆,然后选择具有最大(已发布)的流,然后重复 200 次。每个操作都应该很快。
自从 Google、Facebook、Twitter、Microsoft 和所有大公司都将 mysql 用于生产目的后,我肯定会遗漏一些东西。有经验的吗?
编辑:根据蒂格的回答进行更新。我尝试了索引提示,但似乎没有帮助。结果附在下面,最后。 Mysql order by optimisation 声称解决了他们提出的问题:
我同意 MySQL 可能会使用 复合 blog_id-published-index, 但仅适用于 blog_id 部分 查询。
SELECT * FROM t1 WHERE key_part1=常数 ORDER BY key_part2;
至少 mysql 似乎声称它可以在 WHERE 子句(查询的 blog_id 部分)之外使用。有什么帮助吗?
谢谢, -Prasanna [在 gmail dot com 上的 myprasanna]
如果不存在`articles`,则创建表( `id` int(11) NOT NULL AUTO_INCREMENT, `category_id` int(11) 默认为 NULL, `blog_id` int(11) 默认为空, `cluster_id` int(11) 默认为 NULL, `title` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL, `description` 文本 COLLATE utf8_unicode_ci, `keywords` 文本 COLLATE utf8_unicode_ci, `image_url` varchar(511) 整理 utf8_unicode_ci DEFAULT NULL, `url` varchar(511) 整理 utf8_unicode_ci DEFAULT NULL, `url_hash` varchar(50) 整理 utf8_unicode_ci DEFAULT NULL, `author` varchar(255) 整理 utf8_unicode_ci DEFAULT NULL, `categories` varchar(255) 整理 utf8_unicode_ci DEFAULT NULL, `已发布` int(11) 默认为 NULL, `created_at` 日期时间默认为 NULL, `updated_at` 日期时间 DEFAULT NULL, `is_image_crawled` tinyint(1) 默认为 NULL, `image_candidates` 文本整理 utf8_unicode_ci, `title_hash` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL, `article_readability_crawled` tinyint(1) 默认为 NULL, 主键(`id`), KEY `index_articles_on_url_hash` (`url_hash`), KEY `index_articles_on_cluster_id`(`cluster_id`), KEY `index_articles_on_published`(`已发布`), KEY `index_articles_on_is_image_crawled`(`is_image_crawled`), KEY `index_articles_on_category_id`(`category_id`), KEY `index_articles_on_title_hash` (`title_hash`), KEY `index_articles_on_article_readability_crawled`(`article_readability_crawled`), KEY `index_articles_on_blog_id` (`blog_id`,`published`) ) 引擎=InnoDB 默认字符集=utf8 排序=utf8_unicode_ci AUTO_INCREMENT=562907 ; 从文章中选择 id USE INDEX(index_articles_on_blog_id) WHERE category_id = 11 AND blog_id IN (13,14,15,16,17,18,19,20,21,22,23,24,26,27,6330,6331,8269 ,12218,18889) 按已发布的 DESC LIMIT 380 排序; …… 380 行(11.27 秒) 从文章中解释 SELECT id USE INDEX(index_articles_on_blog_id) WHERE category_id = 11 AND blog_id IN (13,14,15,16,17,18,19,20,21,22,23,24,26,27,6330,6331, 8269,12218,18889) 按已发布的 DESC LIMIT 380\G 排序; ****************************** 1. 行 ************************ ******* 编号:1 选择类型:简单 表:文章 类型:范围 可能键:index_articles_on_blog_id 键:index_articles_on_blog_id 关键长度:5 参考:空 行数:8640 额外:使用where;使用文件排序 一组中的 1 行(0.00 秒)【问题讨论】:
标签: mysql performance indexing