为关系表的所有外键创建覆盖索引和为关系表的每个列(外键)创建一个索引有什么区别?
例如,我有表sales(p_id, e_id, c_id, ammount)
,其中p_id是外键(产品表),e_id是外键(employee表),c_id是外键(customer_table)。表的主键是{p_id, e_id, c_id}
。
哪个更好?
CREATE INDEX cmpindex ON sales(p_id, e_id, c_id)
OR
CREATE INDEX pindex on sales(p_id)
CREATE INDEX eindex on sales(e_id)
CREATE INDEX cindex on sales(c_id)
我主要在关系表和父表上运行连接查询。
答案 0 :(得分:2)
哪一个更好取决于您的实际查询。
要理解的一点是,当您在查询中加入表sales
一次时,它将只使用一个索引(最多)。因此,您需要确保最适合查询的索引。
如果您将sales
表始终加入所有其他三个表(customer
,product
和employee
),那么首选复合索引,假设引擎实际上会使用它而不执行表扫描。
当涉及到结果的顺序时,复合索引中字段的顺序很重要。例如,如果您的查询将按产品(第一个)对结果进行分组,然后按客户订购详细信息,则可以从首先具有产品ID且客户ID为第二个的索引中受益。
但也可能是引擎决定最好先开始扫描表sales
然后再使用各自的主键索引加入其他三个表。在这种情况下,sales
表上不存在使用的索引。
找出的唯一方法是获取查询的执行计划,并查看在定义时将使用哪些索引。
如果sales
表上只有一个查询,则不需要多个索引。但更有可能你有几个查询输出完全不同的结果,有不同的字段选择,过滤器,分组......等等。
在这种情况下,您可能需要多个索引,其中一些索引用于一种查询,另一些索引用于其他索引。请注意,您提出的建议并不相互排斥。您可以从几个复合索引中受益,这些索引只有不同的字段顺序。
显然,大量索引会减慢这些表中的数据更改,因此您还需要考虑这种权衡。
答案 1 :(得分:0)
如果您的查询(搜索)独立地通过每个表的销售进行传播,那么您必须为每个表创建一个单独的索引。 如果没有必要那么你可以去复合。
答案 2 :(得分:0)
正如HoneyBadger评论的那样,你已经有了一个复合索引,因为你的主键本身就是一个索引。
通常,只要您认为每个列都有涉及每个字段的查询,就应该为每个列使用单个索引。
如前所述here,当你有一个复合索引时,它可以处理涉及所有字段的查询,或涉及第一个字段(按顺序),第一个和第二个,或第一个,第二个的查询和第三个在一起。它不会用于仅涉及第二和第三领域的查询。
答案 3 :(得分:0)
其他答案缺少重要的一点。在MySQL中声明外键时,它会在列上创建索引。这在其他数据库中并非(必然),但在MySQL中也是如此。
因此,声明会自动创建这些索引:
CREATE INDEX pindex on sales(p_id);
CREATE INDEX eindex on sales(e_id);
CREATE INDEX cindex on sales(c_id);
(这些索引非常便于处理级联约束并基于外键维护数据完整性。)
如果您恰好在sales(p_id, e_id, c_id, amount)
上声明了索引,则不需要第一个索引 - 它是此索引的子集。但是,还需要其他两个。
是否需要此索引?如其他问题所述,这取决于您要使用索引的查询。我建议从这个主题的documentation开始,了解如何使用索引。
答案 4 :(得分:0)
请注意,只有在查询第一部分,第一和第二部分,第一,第二和第三部分等时才使用复合键上的索引,因此要查询p_id或p_id和e_id等。甚至e_id和p_id将使用索引。实际上,任何包含p_id的查询都将使用此索引。 但是,如果您在e_id或c-id或这两者的任何组合上查询Sales表,将不使用cmpindex并执行全表扫描。
在每个外键上都有一个索引的好处(非唯一索引,因为同一产品,同一员工,同一客户或同一客户可能会有多次销售,从而导致索引中的条目重复) )是查询优化器可以选择使用索引来减少返回的行数,然后对结果集进行顺序搜索。
例如如果查询是针对特定产品对特定客户(无论员工)的销售情况的搜索,并且您的销售额为一百万,则可以使用外键索引cindex将20个销售项目返回给该特定客户,并返回结果集可以非常有效地顺序搜索,以找到其中哪些销售是针对特定产品的。 如果搜索是在Product上执行的,并且使用了pindex,则结果集可能是10,000行(该产品的所有销售额),必须顺序搜索该行才能找到该产品对特定客户的销售额,从而导致查询效率低。
我相信为表保留的统计信息(由优化程序使用)跟踪使用每个索引将为查询返回的平均行数,因此优化程序将能够得出cindex应该为在上面的示例中使用了而不是pindex。另外,您可以在查询中给出提示以指定使用特定的索引。 显然,定期运行UPDATE STATISTICS很重要,因为如果平均每个产品只有10个销售量,执行计划将在上面的示例中使用pindex。