【问题标题】:Function-Based Index on numeric Column数值列上的基于函数的索引
【发布时间】:2011-03-25 13:34:03
【问题描述】:

我有一个包含一些数字列的表格,我必须让它们保持数字,因为大多数时候我会从中受益。但我还需要使用部分匹配对这些列进行通用搜索,所以在我的 where 语句中我会有类似

...where num_col1 like "1234%...

我的问题是:

我可以在 num_col1 上创建一个基于函数的索引,将列转换为 CHAR 吗?我试过了,好像不行。

如果没有,你们对如何加快查询结果还有其他建议吗?

我读到一些可能的解决方案可能是创建原始表的视图并将列类型更改为 varchar 并索引该列,或者另一种解决方案可能是向我的表中添加一个额外的 varchar 列并索引.我想避免这两种解决方案,因为我有一个非常大的表,其中已经包含大量行和大量列。

提前感谢大家, 贝斯特,N。

【问题讨论】:

    标签: mysql indexing sql-tuning


    【解决方案1】:

    MySQL 没有基于函数的索引、虚拟列或索引视图 (afaik)。

    从我的SQL Indexing Tutorial 引用注释on function based indexes in MySQL

    备份解决方案是在表中创建一个包含表达式结果的真实列。该列必须由触发器或应用程序层维护——无论哪个更合适。新列可以像任何其他列一样被索引,SQL 语句必须查询新列(不带表达式)。

    但是,在您的特定情况下,您可能会被任意位置的 LIKE 表达式“%1234%”过滤。在这种情况下,b-tree 将无济于事(在 LIKE performance tuning/indexing 中解释)。这将需要全文索引,这仅适用于 MyISAM。

    【讨论】:

    • 我读了那句话,我想避免添加基本上只是复制原始列的列,它们只是具有不同的类型。所以创建一个只有文本列的镜像表会更有意义。回答你帖子的最后一部分不,我不会面对'%1234%'的情况。我将只有 '1234%' 所以索引将在这些情况下工作:)
    • @Kaiser 基于函数的索引是您需要的功能。它仍然复制数据,但仅在索引中。 MySQL 没有它们,因此您需要使用备份解决方案(假设您不能使用支持基于函数的索引的广告数据库;)。备份解决方案将在表和索引中复制该数据。而且您需要在 WHERE 子句中查询不同的列。这是通用的备份解决方案...
    • 这正是我不想听到的哈哈 :) 我可能会选择备份解决方案 ;) 谢谢 Markus。
    【解决方案2】:

    我认为您使用视图的直觉是正确的,以避免重复数据。但是在一种情况下通过数字优化而在另一种情况下通过字符串搜索优化的需求是什么?根据这些情况,查看编号系统以查看是否可以搜索比字符串比较快得多的数字范围( x >= 12340 和 x

    【讨论】:

    • 视图不可靠,因为我经常在原始表中更新和插入大量数据。并在一个范围内搜索,因为假设我有一列包含 12345678,如果用户搜索“1234”,我希望此列出现在我的查询结果中。
    • 我会这样做以提高速度然后..首先,拉回最大 ID 以查看数字大小。然后让 SQL 生成对象/脚本生成一个 WHERE,搜索每个范围的最大位数。因此,如果您的最大 ID 为 999999,并且用户输入“1234”,则生成的 WHERE 子句将是:“WHERE (id >= 1234 AND id = 12340 AND id = 123400 AND id
    • @robert - 不错的方法 - 看起来有点臃肿,但可能解决了问题。搜索内容的实际要求仍不清楚。它总是开头的 4 位数字吗?注意“智能”键总是一个问题——所以我建议回到原来的桌子设计,也许一开始就把它分开。
    • @randy 同意.. 我的操作是假设桌子已经被大量使用,因此重新设计成本很高,但如果重新设计是一种选择,那么拆分是最好的情况。
    • 试一试.. 即使使用一长串动态生成的“OR”,我猜它最终仍然会比数百万个字符串的字符串比较快得多。不过,这可能是 YMMV,具体取决于您的数据库设置。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-24
    • 1970-01-01
    相关资源
    最近更新 更多