2011-06-17 79 views
0

我正试图提高现有MySQL数据库的性能。MySQL索引 - 如何提高性能?

它是关于餐馆数据库,有两个相关的表:

还有一个供网站的所有实体表,每个实体都有一个唯一的ID, 一个实体可以是几乎任何东西,它可以是一个餐厅,用户和其他许多东西。 有几种实体类型,而餐厅的实体类型是“对象”。

我还要说这个数据库的结构已经存在了很多 所以我不想做大的修改,例如我不打算删除所有实体的表 。 (数据库本身没有数据,但是PHP引擎是这样构建的,所以它很难对结构进行大的修改)。

也有一个表只能为对象,有几种类型在数据库 对象,但餐馆专门将是 搜索了很多,因为这是该网站的主题, 餐馆有几个领域:国家,城市,名称,流派。 在同一个城市和国家不能有两个同名的餐厅, (例如,可以有两个餐厅同名,但在同一个国家的不同城市 或两个同名的餐厅但在不同的国家)

所以从这个事实,我想我应该做一个独特的三列索引的国家,城市和名称列。

另外我想说的是,URL也是以www.domain.com/Country/City/Restuarant-Name的形式构建的,所以国家城市名称的组合应该快速获取,这种类型的查询会发生很多。

但也会有许多其他类型的查询,如:搜索名称为 餐厅(使用LIKE查询,因为搜索的名称可以是全名的一部分 ))城市或某个国家。 搜索某个国家和城市中某个流派的所有餐馆。 和几乎所有可能的组合。

也许是最常用的查询将是:(a)为餐馆名称搜索某市 和国家(这将是一样的,当一个URL被输入,但将使用 LIKE使用的查询),(B )在某个城市和国家搜索某种类型的餐馆。 和最后(C)在搜索餐馆的名字在全球范围(在整个数据库,而不指定城市和国家)

这个表(对象表),目前有PRIMARY KEY是对象的ID, 该ID还使用了很多,将最好的做法是以下?:

  1. 做一个三列的唯一指标了国家,城市的,名称
  2. 再拍(不是唯一的)索引超出名字(所以我上面写的类型c的查询将会执行得很快)
  3. 可能会创建某种子表,其中只包含 表中的餐馆,因此将查询此子表。

我真的很感激任何帮助,因为我(因为如果我决定 做出大的改变我可能会单独从对象 其余的餐馆开始,这是不那么重要)我一直试图决定这个很长一段时间。

ps在对象表中的一些对象将不会有任何类型或任何国家或城市,所以他们将保持NULL,我知道NULL值是允许在一个唯一的键,但它会对 有影响表演?

感谢名单了很多的人谁愿意阅读本长的问题:)

+1

http://stackoverflow.com/questions/6098616/dos-and-donts-for-indexes/ –

+0

@Denis感谢您的链接。为了表现,索引是关键。潘打算。 – Wiseguy

回答

1

,只要你想,你可以思考和计划,但你不会知道肯定,直到你试试,基准什么是最好的,比较你的选择。这就是说,这听起来像你绝对是在正确的轨道上。因为它是从最广泛的命令最窄的选择标准

复合键
你的“国家城市名”复合键似乎是最有用的顺序。我相信你是故意这样做的,因为复合键的值只能从左到右使用。因为名称没有在该索引中排名第一,所以您需要一个单独的密钥,只需名称,如您所述。 NULL的

指数值
imysql.cn“允许索引NULL值真的不会影响性能。”这只不过是没有数据或参考而已,所以我不知道他们如何/如果他们证明了这一点。

拆分表
如果有很多与餐厅记录混合在其他的数据,当然,这可能会减缓事情有点。如果您将表转换为具有相同结构的“餐厅”和“其他”表格,您仍然可以使用简单的UNION轻松查询其组合数据。除非您对数据/减速有所了解,否则我宁愿避免将桌子拆分,除非必要,至少为了简单/一致。

是否有任何可预见的查询当前索引不会考虑,如没有国家的城市?如果是这样,一定要适当地索引涵盖所有可预见的情况。你没有提到它,但我想你也会有一个索引类型


最终,您需要生成大量测试数据并进行尝试。 (确定您最终可能期望得到多少数据,并生成至少三倍的测试数据,以使系统通过它的步伐。)从您描述的内容来看,设计听起来不错,但测试可能会发现意外问题,你可以从不同的索引中受益,等等。如果发现任何问题,你将有一个特定的目标来完成,而不是简单地思考所有假设情景。

+0

感谢很多男士,我想多说一句,我还会有一个评级专栏用于对餐厅进行分类,这是否会对答案产生影响?我假设不能有一个以上的指数,也许只是增加评级并将其作为四列指数? (国家,城市,名称,等级) – fiftyeight

+0

@fiftyeight您的意思是“不能超过一个”_primary key_?因为可以肯定有多少个索引就是你想要的。我认为你不想在这个独特的复合索引中包含_rating_。它不用于识别记录。只需在_rating_列上放置一个非唯一索引。 – Wiseguy

+0

@fiftyeight所以它看起来像你会有四个索引:1)ID上的主键,2)“country-city-name”上的唯一组合索引,3)_name_上的常规索引,4)常规索引on _评分_。应该这样做,除非你发现某些查询由于某种原因不能使用这些查询。如果你确实发现了这一点,那么这真的可以帮到你。 :-) – Wiseguy