Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 使用LEFT()函数的查询性能不佳_Mysql_Performance - Fatal编程技术网

Mysql 使用LEFT()函数的查询性能不佳

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不会对应用了函数的列使用索引 其

我使用内部连接和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不会对应用了函数的列使用索引

其他数据库允许基于函数的索引


您可以创建一个只包含前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
子句不使用索引,因为谓词不是。@HamletHakobyan
LEFT()
不能本质上与索引一起使用(我可以理解
RIGHT()
不是可搜索的)。。这并不是说我期望MySQL有太多的优化,但我希望它能比哈姆雷特评论的翻译更多:因为你正在对WHERE子句中的内容进行字符串操作,MySQL不能使用该列上的任何索引,因为它必须对表中的每一行执行该操作,以确定表达式是否为真。表上的索引是什么?表有多大?添加全文索引并对您的
WHERE
子句使用match,因为谓词不使用索引。@HamletHakobyan
LEFT()
不能与索引一起使用似乎很可笑(我可以理解
RIGHT()
不是可搜索的)。。这并不是说我期望MySQL有太多的优化,但我希望它能比哈姆雷特评论的翻译更多:因为你正在对WHERE子句中的内容进行字符串操作,MySQL不能使用该列上的任何索引,因为它必须对表中的每一行执行该操作,以确定表达式是否为真。表上的索引是什么?表有多大?添加全文索引并使用match againstI。我现在将尝试此方法。只有表B需要索引吗?它必须是多列索引吗?ThanksTableB应该有我在答案中描述的综合指数。我现在就试试这个。只有表B需要索引吗?它必须是多列索引吗?ThanksTableB应该有我在答案中描述的综合指数。