Mysql 使用LEFT()函数的查询性能不佳
我使用内部连接和WHERE with LEFT函数来匹配记录的前8个字符Mysql 使用LEFT()函数的查询性能不佳,mysql,performance,Mysql,Performance,我使用内部连接和WHERE with LEFT函数来匹配记录的前8个字符 INSERT INTO result SELECT id FROM tableA a INNER JOIN tableB b ON a.zip=b.zip WHERE LEFT(a.street,8)=LEFT(b.street,8) a.street和b.street都编制了索引(部分索引8) 查询未在24小时以上完成。我想知道索引是否有问题,或者是否有更有效的方法来执行此任务Mysql不会对应用了函数的列使用索引 其
INSERT INTO result SELECT id FROM tableA a
INNER JOIN tableB b ON a.zip=b.zip
WHERE LEFT(a.street,8)=LEFT(b.street,8)
a.street
和b.street
都编制了索引(部分索引8)
查询未在24小时以上完成。我想知道索引是否有问题,或者是否有更有效的方法来执行此任务Mysql不会对应用了函数的列使用索引 其他数据库允许基于函数的索引
您可以创建一个只包含前8个字符a.street和b.street的列,并对它们进行索引,这样会更快。Mysql不会对应用了函数的列使用索引 其他数据库允许基于函数的索引 您可以创建一个列,其中只包含a.street和b.street的前8个字符,并对它们进行索引,这样会更快。这是您的查询:
INSERT INTO result
SELECT id
FROM tableA a INNER JOIN
tableB b ON a.zip=b.zip
WHERE LEFT(a.street,8)=LEFT(b.street,8);
MySQL不够聪明,无法在比较中使用前缀索引。它将使用前缀索引进行类似的
和直接字符串比较。如果我假设id
是从tableA
组合而来的,那么以下操作可能会执行得更好:
INSERT INTO result(id)
SELECT id
FROM tableA a
WHERE exists (select 1
from tableB b
where a.zip = b.zip and
b.street like concat(left(a.street, 8), '%')
);
您需要的索引是tableB(zip,street(8))
或tableB(zip,street)
。这可以使用索引的两个组件。在任何情况下,即使不能同时使用索引的两侧,它也可能获得更好的性能。这是您的查询:
INSERT INTO result
SELECT id
FROM tableA a INNER JOIN
tableB b ON a.zip=b.zip
WHERE LEFT(a.street,8)=LEFT(b.street,8);
MySQL不够聪明,无法在比较中使用前缀索引。它将使用前缀索引进行类似的
和直接字符串比较。如果我假设id
是从tableA
组合而来的,那么以下操作可能会执行得更好:
INSERT INTO result(id)
SELECT id
FROM tableA a
WHERE exists (select 1
from tableB b
where a.zip = b.zip and
b.street like concat(left(a.street, 8), '%')
);
您需要的索引是
tableB(zip,street(8))
或tableB(zip,street)
。这可以使用索引的两个组件。在任何情况下,即使不能同时使用索引的两侧,它也可能获得更好的性能。您的WHERE
子句不使用索引,因为谓词不是。@HamletHakobyanLEFT()
不能本质上与索引一起使用(我可以理解RIGHT()
不是可搜索的)。。这并不是说我期望MySQL有太多的优化,但我希望它能比哈姆雷特评论的翻译更多:因为你正在对WHERE子句中的内容进行字符串操作,MySQL不能使用该列上的任何索引,因为它必须对表中的每一行执行该操作,以确定表达式是否为真。表上的索引是什么?表有多大?添加全文索引并对您的WHERE
子句使用match,因为谓词不使用索引。@HamletHakobyanLEFT()
不能与索引一起使用似乎很可笑(我可以理解RIGHT()
不是可搜索的)。。这并不是说我期望MySQL有太多的优化,但我希望它能比哈姆雷特评论的翻译更多:因为你正在对WHERE子句中的内容进行字符串操作,MySQL不能使用该列上的任何索引,因为它必须对表中的每一行执行该操作,以确定表达式是否为真。表上的索引是什么?表有多大?添加全文索引并使用match againstI。我现在将尝试此方法。只有表B需要索引吗?它必须是多列索引吗?ThanksTableB应该有我在答案中描述的综合指数。我现在就试试这个。只有表B需要索引吗?它必须是多列索引吗?ThanksTableB应该有我在答案中描述的综合指数。