【问题标题】:MySQL Index on first part of string字符串第一部分的MySQL索引
【发布时间】:2011-09-21 22:23:36
【问题描述】:

我在 MySQL 中查询一个非常大的表(超过 3M 条记录),其中包含 category_id、subcategory_id 和 zipcode。数据库中的 zip 可能是也可能不是 10 个字符。

目的是获取指定 zip 的某个半径内的所有 cat/subcat 项目。我有一个函数,它返回一个指定的 5 位数拉链列表。然后将此列表提供给我的查询,如下所示...

SELECT whatever
FROM tblName
WHERE cat_id = 1
AND subcat_id = 5
AND LEFT(zip,5) IN (11111,22222,33333,44444,55555)

我有一个关于 cat_id、subcat_id 和 zip 的复合索引,但在某些情况下 10 个字符的 zip 可能会被丢弃。我可以以某种方式索引 LEFT(zip,5) 吗?

【问题讨论】:

  • 你有这个查询的查询计划吗?这应该告诉你它是如何工作的。在考虑其他索引之前拥有这些信息应该是有用的。
  • 不,您不能在索引中使用函数。在 Oracle 和 PostgreSQL 中可以,但在 MySQL 中不行。
  • “查询计划”是指在查询上运行 EXPLAIN... 吗?我没想到。谢谢。 @Johan:我在考虑 Oracle,我认为......很久以前做过 PL/SQL,并认为这个想法似乎是可能的。

标签: mysql indexing


【解决方案1】:

直接回答您的问题:是的,您可以索引 left(zip, 5)。

alter table tblName add index (zip(5));

如果您希望查询能够使用索引来搜索所有列:

alter table tblName add index (cat_id, subcat_id, zip(5));

【讨论】:

【解决方案2】:

您应该有一个包含正常 5 位 zip 的列和包含所有额外数字的列,并让 SQL 正常处理它。有很多方法可以做到你所说的,但这是迄今为止最有效的解决方案。

【讨论】:

    【解决方案3】:

    如果要使用索引,请将查询更改为:

    SELECT whatever
    FROM tblName
    WHERE cat_id = 1
    AND subcat_id = 5
    AND (   zip LIKE '11111%'
         OR zip LIKE '22222%'
         OR zip LIKE '33333%'
         OR zip LIKE '44444%'
         OR zip LIKE '55555%')
    

    另一个选项是非规范化您的表(应该是最后一个选项)并添加一个额外的字段,其中包含 zip 中最左边的 5 个字符。 然后你可以这样做:

    SELECT whatever
    FROM tblName
    WHERE cat_id = 1
    AND subcat_id = 5
    AND LEFTzip5 IN (11111,22222,33333,44444,55555)
    

    不要忘记在字段 leftzip5 上放置索引。

    【讨论】:

    • 谢谢。我想过这个。这是我们继承的医生数据(地址等)的表,zip 是低效的 varchar(255)。我考虑过创建 LEFT(x,5) 的 char(5) 只是为了使表格更小……现在有 3M 条记录,将近 900MB……
    猜你喜欢
    • 2012-07-16
    • 1970-01-01
    • 2014-11-06
    • 2015-11-17
    • 2012-12-30
    • 2020-06-27
    • 2018-12-07
    • 2011-09-17
    • 1970-01-01
    相关资源
    最近更新 更多