我想制作一个包含4列的表格。一个是主键,其他三个列是对其他表的列的引用。我想用它来连接这四个表来制作搜索过滤器。这些联接需要时间。
我在想我应该索引这些列,因为我读到在连接条件中使用的列上添加索引[使它们运行得更快]。我的问题是,如果表的所有列都被编入索引会有问题吗?或者还有其他方法可以降低搜索过滤器的时间复杂度。提前谢谢。
更多提示: 表1(主要搜索)-1000个条目 首要的关键 FK1 FK2 FK3
表2-800条目 PK1 ..(8-9栏)
表3-700条目 PK2 ..(10-12列)
表2-850条目 PK3 ..(7-8栏)
答案 0 :(得分:9)
创建索引需要额外的磁盘空间,而且过多的索引可能会导致文件系统大小限制引起的问题,必须仔细考虑选择要索引的正确字段。
由于索引仅用于加速搜索记录中的匹配字段,因此,仅用于输出的索引字段仅仅是在执行插入或删除操作时浪费磁盘空间和处理时间,因此应该避免。同样考虑到二进制搜索的性质,数据的基数或唯一性很重要。对基数为2的字段进行索引会将数据分成两半,而基数为1,000则会返回大约1,000条记录。如此低的基数,有效性会降低到线性排序,如果基数大于记录数的30%,查询优化器将避免使用索引,从而有效地使索引浪费空间。
最好在列组上添加索引。
答案 1 :(得分:4)
要正确索引数据以提高性能,您需要了解数据。假设我说我正在创建人口普查数据库表:
CREATE TABLE CENSUS
(
ID INTEGER NOT NULL,
GENDER CHAR(1) NOT NULL,
FAVOURITEFOOD NVARCHAR(20) NOT NULL,
STATE NVARCHAR(20) NOT NULL
);
由于处理数据,我可能知道:
如果我想搜索喜欢烤肉并住在加利福尼亚的男性,我会考虑制作多列索引,将STATE放在首位(STATE,GENDER,FAVOURITEFOOD)。我将FAVOURITEFOOD作为索引中的最后一列。这是因为STATE过滤器将数据削减25%,而FAVOURITEFOOD将返回数据库的大部分(不比全表扫描更好)。
如果我想搜索喜欢吃素食并住在纽约的女性,我会考虑制作一个多列索引并首先放入FAVOURITEFOOD(FAVOURITEFOOD,STATE,GENDER)。在这里,FAVOURITEFOOD将数据减少20%,因此它比其他两列更好。
如果我经常运行两个查询,我应该制作哪个索引?答案是:
CREATE INDEX IX_CENSUS_001 ON CENSUS (STATE, GENDER, FAVOURITEFOOD);
CREATE INDEX IX_CENSUS_002 ON CENSUS (FAVOURITEFOOD, STATE, GENDER);
ANALYZE TABLE CENSUS;
ANALYZE TABLE命令存储表的密钥分发。现在,当您运行任一查询时,它将确定IX_CENSUS_001或IX_CENSUS_002是否是执行计划的最佳索引。
如果,我希望开始运行不同类型的查询,我将停止并再次考虑我的数据。我可能需要添加一个新索引,我可能需要再次运行ANALYZE TABLE。
所以,回到你的场景;它取决于您在表中的数据以及您希望在其上执行的查询。
答案 2 :(得分:3)
指数不是神奇药丸。
当然,它们可以加快查询速度,但它们也会降低写入速度(插入/更新/删除)并占用宝贵的RAM。
小心使用它们。
答案 3 :(得分:3)
在引用表列中,必须有一个索引,其中外键列以相同顺序列为第一列。
如果索引不存在,则会自动在引用表上创建索引。
通过以下文章了解击球手:How To Index For Joins With MySQL
答案 4 :(得分:1)
向列添加索引意味着数据库必须在每次写入时执行更多工作,但可以节省一些读取的时间。
如果您的查询花了很长时间为联接添加覆盖索引可以帮助加快速度,但与所有优化工作一样,请确保您有适当的指标与“优化”之前和之后进行比较!
但是,由于您每列都要加入一个表,因此您不需要索引,因为您已经拥有主键并且无论如何都需要读取完整行。
答案 5 :(得分:0)
我认为对所有四列进行索引并不能真正提高性能,因为您仍然需要完整的索引扫描,这种扫描基本上与全表扫描相同。您的索引只是表格中数据的重复。你可以粘贴你的查询吗?
答案 6 :(得分:0)
如果将主表的主键添加到其他表并加入此字段上的表,则代替添加索引会更快。