MySQL查询速度慢 - 可能是索引问题?

时间:2009-01-16 14:40:12

标签: mysql

首先,这是我的查询:(注意:我知道SELECT *是不好的做法我只是将其切换以使查询更具可读性

SELECT pcln_cities.*,COUNT(pcln_hotels.cityid) AS hotelcount
  FROM pcln_cities
  LEFT OUTER JOIN pcln_hotels ON pcln_hotels.cityid=pcln_cities.cityid
  WHERE pcln_cities.state_name='California' GROUP BY pcln_cities.cityid
  ORDER BY hotelcount DESC
  LIMIT 5

所以我知道要解决类似的事情,你将EXPLAIN添加到查询的开头,但我不是100%确定如何阅读结果,所以这里是:

alt text http://www.andrew-g-johnson.com/query-results.JPG

奖励指向一个答案,告诉我在EXPLAIN结果中要查找的内容

编辑城市表有以下索引(或者是索引吗?)

  • cityid
  • STATE_NAME
  • 我刚刚添加了两个,因为我认为它可能有所帮助(它没有)

酒店表有以下索引(或者是索引吗?)

  • cityid

3 个答案:

答案 0 :(得分:3)

嗯,你的查询中有一些不太正确的东西。 您使用聚合函数(计数),但您只需按ID分组。 通常,您应该对选择列表中的所有列进行分组,这些列不是聚合函数。

正如您现在已经指定了查询,恕我直言,DBMS永远无法正确地确定他应该为那些不是聚合的列显示哪些值......

如果你的查询是这样编写的,那就更正确了:

select cityname, count(*)
from city inner join hotel on hotel.city_id = city_id
group by cityname
order by count(*) desc

如果您没有cityName的索引,并且您对cityname进行了过滤,那么如果您在该列上放置索引,它将提高性能。

简而言之:在经常用于过滤或排序的列上添加索引可以提高性能。 (这只是简单地说,你可以把它当作'指南',但每种情况都不同。有时添加一个跨越多列的索引会有所帮助。 此外,请记住,如果您更新或插入记录,索引也需要更新,因此添加/更新/删除记录会有轻微的性能成本)

另一个可以提高性能的方法是使用内连接而不是外连接。我不认为有必要在这里使用外连接。

答案 1 :(得分:0)

您好像没有pcln_cities.state_name或pcln_cities.cityid的索引?尝试添加它们。

鉴于你已经更新了你的问题,说你确实有这些索引,我只能建议你的数据库目前在加利福尼亚州占优势的城市,所以查询优化器决定更容易进行表扫描抛弃非加利福尼亚州,而不是使用该指数来挑选加利福尼亚州。

答案 2 :(得分:0)

您的查询看起来很好。是否有其他东西可以锁定您需要的记录?桌子特别大吗?我怀疑数据是问题,因为没有那么多的酒店......

我遇到过与MySQL类似的问题。经过一年多的调整,修补和认为我是一个SQL假人,我切换到SQL Server Express。具有完全相同数据的完全相同的查询将在SQL Server Express中快速运行2-5个数量级。对于中等复杂的查询(5 +表),MySQL似乎特别困难。我认为在SUN收购该组织后,MySQL优化器变得迟钝了......