假设我有一张50 columns
的表格。我想做点什么:
SELECT * FROM table WHERE column1=value1 OR column2=value2 OR ...
我怎样才能有效地做到这一点?
我可以在多个/所有列中添加一堆indexes
或索引。这会有帮助吗?
我可以使用列(secondary table
)创建id, field_name, field_value
,然后在每列上编制索引,现在我的OR仅适用于索引的2列。
我还能做什么?
了解更多信息:
答案 0 :(得分:0)
当你遇到这样的场景时,它通常表明可能有空间来规范化表格(你的场景B)。如果没有关于列实际保存的数据以及整体表访问模式的更多信息,将很难知道。
话虽如此,如果没有任何类型的表结构更改,您只需要在每个列上都有一个索引,可能要查询,以防止进行全表扫描。
答案 1 :(得分:0)
搁置有关更改数据库设计的讨论......
组合索引(查询中引用的许多或大多数列的索引)对您的查询没有帮助,查询有一堆OR
'd colN = 'foo'
谓词。 MySQL不会使用该索引来满足您的查询。即使它使用索引,基本表中仍然会有其他列需要在每一行上进行检查,因此MySQL很可能只访问所有数据页而根本不使用索引。 (如果您的查询中碰巧有GROUP BY或ORDER BY,MySQL可能会使用索引来优化这些操作,特别是如果它是一个“覆盖”索引,其中包含查询引用的每一列。
另一方面,如果您使用OR colN = 'foo' OR colN = 'bar'
检查了每个列(作为索引中的前导列)的单独的单独索引,则MySQL可能会考虑使用“索引”合并“您的查询计划。
但它必须是每列的索引。如果您的查询甚至只检查一个不是任何索引中的前导列的列,那么MySQL将别无选择,只能检查表中的每一行。因此,在“many”列上使用单独的索引对查询没有帮助,因为很可能会使用NONE索引。
即使你确实有一个单独的索引用于每一个被引用的列的每一列,它可能是MySQL对返回的总行数的估计(从每个索引合并)太大,并且MySQL很可能决定“索引合并”太昂贵,而选择全表扫描。
总之,您只有两个索引选项可以帮助您进行查询(而且它们都不是一个非常好的选择):
1)具有前导列的“覆盖索引”,可用于满足GROUP BY或ORDER BY子句(避免“使用filesort”操作“
2)查询中OR colN = 'literal'
谓词检查的每一列(作为前导列)的单独索引
但同样,这些都不是一个好的选择。