Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
多计数(*)查询的MySQL索引_Mysql_Database_Indexing_Query Optimization - Fatal编程技术网

多计数(*)查询的MySQL索引

多计数(*)查询的MySQL索引,mysql,database,indexing,query-optimization,Mysql,Database,Indexing,Query Optimization,关于索引,我迷路了。我有一个为客户端构建的中等复杂的web应用程序,它有几个count(*)查询,这些查询都运行得非常慢(0.3秒) 这里有一个简单的例子 SELECT COUNT( * ) AS `count` FROM `vehicles` WHERE `VehicleLocation_province` = 'Alberta' AND `default_image_URI` IS NOT NULL AND `default_image_URI` != '' 下面是解释

关于索引,我迷路了。我有一个为客户端构建的中等复杂的web应用程序,它有几个count(*)查询,这些查询都运行得非常慢(0.3秒)

这里有一个简单的例子

SELECT COUNT( * ) AS  `count` 
FROM  `vehicles` 
WHERE  `VehicleLocation_province` =  'Alberta'
AND  `default_image_URI` IS NOT NULL 
AND  `default_image_URI` !=  ''
下面是解释

 1 SIMPLE vehicles ref VehicleLocation_province,VehicleLocation_province_...     VehicleLocation_province 2 const 14128 Using where
我甚至不能让这个查询使用适当的索引,更不用说一些更复杂的查询,比如

SELECT * , ( 6371 * ACOS( COS( RADIANS( 53.543564 ) ) * COS( RADIANS( lat ) ) * COS( RADIANS( lng ) - RADIANS( - 113.490456 ) ) + SIN( RADIANS( 53.543564 ) ) * SIN( RADIANS( lat ) ) ) ) AS  `distance` 
FROM  `vehicles` 
WHERE  `Make` =  'Pontiac'
AND  `BodyStyle` =  'Sedan'
AND  `VehiclePrice` >=  '1'
AND  `VehiclePrice` <=  '36000'
AND  `VehiclePrice` IS NOT NULL 
AND  `default_image_URI` IS NOT NULL 
AND  `default_image_URI` !=  ''
HAVING `distance` < 50
ORDER BY `VehicleReceivedDate` DESC LIMIT 25

我知道我需要尽可能避免临时表和文件端口。。。但是,当必须在每个请求上使用不同的where参数分组和排序来执行这些count(*)查询时,这实际上是如何实现的呢?

好的,获取索引加速查询的唯一方法是让索引覆盖足够的条件,以使选择性变得有用(或者让RDBMS能够使用索引来计算聚合,如count)

不要忘记,在
(Make)
(BodyStyle)
上建立索引与在
(Make,BodyStyle)
上建立索引是不同的

在第一次查询中,当您需要对记录进行计数时,包含
default\u image\u URI
VehicleLocation\u province
的索引的存在应该足以让mysql不进行表扫描,而是从索引中检索计数

您可以通过创建一个索引
(VehicleLocation\u province,默认的\u image\u URI)
,然后运行查询和/或检查解释来检查这一点

在第二个查询中,您遇到了与具有更多条件的查询类似的情况(只要它们都是和条件就好),并且它不是关于计数记录,而是实际上从表中检索数据并进行排序

以下是几点注意事项:

  • 请注意,您的条件
    不是空的
    !='
    -如果这些条件通常出现在您的查询中,那么这些条件表明您的设计不正确,并且您已经将不同的实体反规范化为一个表,因此现在您必须在每次使用数据时对它们进行排序(这只是一个指示,我假设您经常应用这些条件,这可能不是真的)
  • 话虽如此,如果您查看第二个查询,如果Make和BodyStyle包含一个复合索引,并且具有低选择性,那么查询仍然会执行得很快
  • mysql必须选择一个索引来访问数据,并且在给定统计信息和可用条件的情况下,它将尝试选择返回最少行数的索引(以便进一步的条件必须循环通过最少数量的记录)-如果该索引仅有助于减少结果集,则将使用文件排序来完成排序。为了使索引对选择行和排序都有用,它应该具有有用的顺序或索引列,例如在上面的查询索引中,
    (Make、BodyStyle、VehiclerReceivedDate)
    可以做到这一点
  • 在表中添加适当的索引应该会有所帮助,但索引无法解决设计问题

另一个我没有考虑过的选项(我现在认为这是理想的解决方案)在索引和性能方面,使用Sphinx这样的搜索服务器来处理繁重的工作。Sphinx可以在多个不同的搜索配置中对多个列进行分组和计数以及全文和属性搜索/过滤

斯芬克斯甚至可以使用SetGeoAnchor($attrlat,$attrlong,$lat,$long)

当运行复杂的搜索查询试图重新发明轮子并最终得到荒谬的多列索引列表试图覆盖所有类型的用例时,这没有什么意义

我希望我在项目早期就想到了搜索服务器——现在,在性能问题上挽回面子有点晚了


这是InnoDB还是MyISAM?它们在性能、索引和计数(*)方面完全不同。@cherouvim,它们肯定不是完全不同:)-一些一般规则应该仍然适用于MyISAM。显然计数(*)性能在InnoDB中受到严重影响(我已经读过)解释得很好。我也喜欢解释某些事情是如何/为什么发生的,而不仅仅是给出答案。我发现这篇文章有助于解释实际的“规则”让MySQL使用组索引是必须遵循的——我现在有几个查询运行得更顺畅,对多列索引排序有了更深入的了解。我回去优化模型,以某种方式构造查询,使它们可以使用更通用的索引,这一项目将大大受益。我不确定这背后的理论(有许多可变参数)不幸的是,这个项目的时间快到了。索引+查询缓存似乎以足够的性能完成了这项任务。谢谢大家。@FelixHCat,很乐意提供帮助。关于链接,请记住它专门针对分组(您的查询不使用它)。此外,如果我的答案有帮助,请随意投票并接受它。@FelixHCat,关于查询缓存-应该考虑它,但不要使用它来评估性能-如果结果集小于my.cnf中的
query\u cache\u size
,则在第二次运行时,它将使执行时间始终为零。使用
选择SQL\u NO\u cache
评估性能+解释(或理想情况下使用缓存,但创建真实的测试工作负载,该工作负载还将以真实的方式进行更新,从而使缓存失效=这并不是那么简单)。
1 SIMPLE vehicles ref Make,BodyStyle,VehicleLocation_province_2 Make 99 const 5821 Using where; Using filesort