【问题标题】:Performance of selecting articles from multiple categories从多个类别中选择文章的性能
【发布时间】:2016-03-03 23:20:38
【问题描述】:

表格

CREATE TABLE IF NOT EXISTS `articles` ( `id` int(11) NOT NULL, `category_id` int(11) NOT NULL, `title` varchar(100) NOT NULL, `created` int(11) NOT NULL, `updated` int(11) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ; ALTER TABLE `articles` ADD PRIMARY KEY (`id`), ADD KEY `category_id` (`category_id`,`created`);

我的测试:

查询1

SELECT sql_no_cache * FROM `articles` WHERE category_id=1 order by created limit 0,15
平均时间:0.0003

解释

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE articles ref category_id category_id 4 const 1029 Using where

查询2

SELECT sql_no_cache * FROM `articles` WHERE category_id=1 order by updated limit 0,15
平均时间:0.0019

解释

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE articles ref category_id category_id 4 const 1029 Using where; Using filesort

查询3

SELECT sql_no_cache * FROM `articles` WHERE category_id in (1,2,3) order by created limit 0,15
平均时间:0.0018

解释

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE articles range category_id category_id 4 NULL 1105 Using where; Using filesort

查询4

SELECT sql_no_cache * FROM `articles` WHERE category_id in (1,2,3) order by updated limit 0,15
平均时间:0.0018

解释

id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE articles range category_id category_id 4 NULL 1105 Using where; Using filesort

我的最终需求是query3

但从测试来看,我认为只有 query1 使用了索引,因为执行时间比其他的要短得多。

问题:

  1. created 上有索引,updated 上没有索引,为什么 query3query4 节省了执行时间?
  2. 如何让 query3 使用索引,或者如何提高 Query3 的性能?

【问题讨论】:

  • @Yossi 类别 ID 可以是任何类型。用例是:用户订阅了几个分类,系统根据他订阅的分类展示文章。
  • 你能发布解释吗?您假设没有使用索引,但情况可能并非如此。响应时间因许多其他不相关的因素而异...
  • 您在 createdcategory_id 上是否有索引,或者两者都有索引(如果有,按什么顺序)?
  • @NevilleK 我测试了 100 次以获得平均执行时间,还添加了“sql_no_cache”。添加了解释。
  • @Kickstart 我更新了问题并添加了完整的表格结构。

标签: mysql


【解决方案1】:

根据MySQL document,如果“查询在索引的非连续部分上使用 ORDER BY”,MySQL 不能使用索引进行排序。 “in”子句就是这种情况。

如果您的 ID 列是一个自动递增的整数,并且 created 是指记录的创建日期,您可以改为按 ID 排序。这将实现我相信你正在尝试做的事情,但它当然有点像黑客......

【讨论】:

  • 明白。但正如我所说,会有大量的类别,意味着最近的10,000篇文章可能只包含不到10行被选中的内容。这就是我对“按ID排序”的关注。我的想法之一是获取最近更新的类别的 10 个 ID,并为每个类别进行 10 个“按创建排序”查询,然后合并结果。
【解决方案2】:

您是否使用“created”是您不用作字段名称的表关键字。 但是
从 category_id in(1,3,7,12,234,333,456) 排序的文章中选择标题 created DESC 限制 0,20 或者 从文章中选择 art.title 作为 art where art.category_id in(1,3,7,12,234,333,456) order by art.created DESC limit 0,20

试试这个方法

【讨论】:

  • 我试过但结果是一样的。我已经更新了我的问题,让它更清楚,你能再看一下吗?
猜你喜欢
  • 2015-01-13
  • 1970-01-01
  • 1970-01-01
  • 2016-09-03
  • 2021-12-12
  • 1970-01-01
  • 2015-12-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多