【问题标题】:Getting Count(*) vs Actual Data has performance implications获取计数(*)与实际数据对性能有影响
【发布时间】:2016-03-09 20:02:18
【问题描述】:

我无法理解以下两个查询。第一个仅获取整个结果集的计数。

第二个获取实际数据,但将结果集限制为 10 行。

  • 不知何故,第一个不能使用索引。我尝试使用USE INDEX (timestamp_index,Fulltext_title,Fulltext_description) 无济于事。
  • count查询不需要order by,但我只是想看看它是否可以这样使用索引。
  • 据我所知,WHERE 子句是相同的,据我所知,这是选择索引的最大因素。

获取计数

SELECT count(*) as total FROM table1 
WHERE 1=1
AND type in ('category1','category3','category2') 
AND ( 
    MATCH(title) AGAINST (' +"apple"' IN BOOLEAN MODE)
    OR 
    MATCH(description) AGAINST (' +"apple"' IN BOOLEAN MODE) 
    )
ORDER BY timestamp DESC
;
+-------+
| total |
+-------+
|   798 |
+-------+
1 row in set (3.75 sec)

解释扩展

+----+-------------+----------+------+---------------+------+---------+------+--------+----------+-------------+
| id | select_type | table    | type | possible_keys | key  | key_len | ref      | rows   | filtered | Extra       |
+----+-------------+----------+------+---------------+------+---------+------+--------+----------+-------------+
|  1 | SIMPLE      | table1   | ALL  | NULL          | NULL | NULL    | NULL | 669689 |   100.00 | Using where |
+----+-------------+----------+------+---------------+------+---------+------+--------+----------+-------------+

获取实际结果

SELECT id, title,desciption,timestamp  FROM table1
WHERE 1=1
AND type in ('category1','category3','category2') 
AND ( 
    MATCH(title) AGAINST (' +"apple"' IN BOOLEAN MODE)
    OR 
    MATCH(description) AGAINST (' +"apple"' IN BOOLEAN MODE) 
    )
ORDER BY timestamp DESC
LIMIT 0, 10 ;

10 行(0.06 秒)

解释扩展

+----+-------------+----------+-------+---------------+------+---------+------+------+------------+-------------+
| id | select_type | table    | type  | possible_keys | key  | key_len | ref      | rows | filtered   | Extra       |
+----+-------------+----------+-------+---------------+------+---------+----   --+------+------------+-------------+
|  1 | SIMPLE      | table1 index | NULL          | timestamp_index   | 21          | NULL |   10 | 6696890.00 | Using where |
+----+-------------+----------+-------+---------------+------+---------+------+------+------------+-------------+

【问题讨论】:

  • limit 对优化器的影响非常大,我不确定你要问这个问题 - 这两个查询完全不同。
  • 这个限制会让它运行得更快。 Count(*) 必须进行全表扫描,尤其是在第一次运行时。它可能会提高后续调用的性能。
  • 好的 ... 让我改一下 .. 我怎样才能让第一个查询使用索引 .. 可能就像在第二个查询中使用的那样。

标签: mysql indexing database-performance full-text-indexing


【解决方案1】:

第二次查询。你想要前 10 个元素。所以优化器使用时间戳索引,对表进行排序并不断检查行,直到找到与您的WHERE匹配的 10 个元素

在您的第一个查询中,数据库必须扫描整个数据库以查找与您的查询匹配的元素,因此您的 ORDER BY 没有帮助,因为您想计算与您所在位置匹配的总行数。

现在还取决于您如何定义索引。你有TypeTitleDescription 的索引吗?你有综合索引吗?

查看这个MySQL索引TIPS

【讨论】:

    【解决方案2】:

    我找到了答案……我结合了这两个索引。所以我们不必仅仅因为我们正在做一个计数(*)而进行全表扫描

    SELECT count(*) as total FROM table1 WHERE 1=1
        AND type in ('category1','category2','category3') 
        AND MATCH(title, description) AGAINST (' +"apple"' IN BOOLEAN MODE)  
    ;
    
    +----+-------------+----------+----------+----------------------+----------------------+---------+------+------+----------+-------------+
    | id | select_type | table    | type     | possible_keys        | key                  | key_len | ref  | rows | filtered | Extra       |
    +----+-------------+----------+----------+----------------------+----------------------+---------+------+------+----------+-------------+
    |  1 | SIMPLE      | table1   | fulltext | FT_title_description | FT_title_description | 0       | NULL |    1 |   100.00 | Using where |
    +----+-------------+----------+----------+----------------------+----------------------+---------+------+------+----------+-------------+
    +-------+
    | total |
    +-------+
    |   798 |
    +-------+
    1 row in set (0.83 sec)
    

    【讨论】:

      猜你喜欢
      • 2017-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-20
      • 2011-07-07
      • 2018-09-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多