Mariadb 使用修改的索引进行左慢速连接

Mariadb 使用修改的索引进行左慢速连接,mariadb,Mariadb,我有一个旧的MySQL查询来查找一个始终运行良好的免费ID(0.0325秒)。但现在我换成了MariaDB,速度非常慢(超过30秒) “codice”是主要指标 旧数据库是MySQL 5.1.73,新数据库是MariaDB 5.5.52 我复制了表(导入/导出数据库和数据),删除并重新创建了索引,但新数据库中的查询总是很慢 我读过一些答案,其中更改的索引(codice+1)会破坏索引并强制MySQL扫描整个表,但我认为情况并非如此,因为在旧的MySQL数据库中,查询速度很快 有什么建议吗 编辑

我有一个旧的MySQL查询来查找一个始终运行良好的免费ID(0.0325秒)。但现在我换成了MariaDB,速度非常慢(超过30秒)

“codice”是主要指标

旧数据库是MySQL 5.1.73,新数据库是MariaDB 5.5.52

我复制了表(导入/导出数据库和数据),删除并重新创建了索引,但新数据库中的查询总是很慢

我读过一些答案,其中更改的索引(codice+1)会破坏索引并强制MySQL扫描整个表,但我认为情况并非如此,因为在旧的MySQL数据库中,查询速度很快

有什么建议吗

编辑
桌子

与Maria Db解释

| id|select_type|table |type    |possible_keys|key      |key_len|ref |rows  |Extra  
    ------------------------------------------------------------------------------
| 1 | SIMPLE    |clfoco|range   |PRIMARY      |PRIMARY  |62     |NULL|24549 |Using where; Using index  
| 1 | SIMPLE    |clfoco|index   |PRIMARY      |PRIMARY  |62     |NULL|25182 |Using where; Using index; Using join buffer (flat, BNL join)
用Mysql 5.1.73进行解释

MariaDB上的执行时间为0.0294秒

解释扩展:

id|select_type       |table |type |possible_keys|key    |key_len|ref |rows  |filtered|Extra
1 |PRIMARY           |a     |range|PRIMARY      |PRIMARY|62     |NULL|24549 |100.00  |Using where; Using index
2 |DEPENDENT SUBQUERY|clfoco|range|PRIMARY      |PRIMARY|62     |NULL|24549 |100.00  |Range checked for each record (index map: 0x1)

子选择看起来有点模糊,这总是很危险的,因为即使它现在没有混淆优化器,它也可能在将来的版本中出现(就像已经发生的那样)。如果没有子选项,我会写这篇文章:

select a.codice+1 as codice
from clfoco a
left join clfoco b
    on b.codice=a.codice+1
    and (substring(b.codice,9) between '0000001' and '9999999')
    and b.codice like '1201__%'
where b.codice is null
and (substring(a.codice,9) between '0000001' and '9999999')
and a.codice like '1201__%'
limit 1;
这是否会减少优化器的困惑

从您添加的NOT EXISTS版本的解释来看,它似乎在使用
如'1201_u_%'
对依赖子查询进行索引,而它不应该这样做。试试这个:

select a.codice+1 as codice
from clfoco a
left join clfoco b on b.codice=a.codice+1
where b.codice is null
and (substring(a.codice,9) between '0000001' and '9999999')
and a.codice like '1201__%'
and (substring(a.codice+1,9) between '0000001' and '9999999')
and a.codice+1 like '1201__%'
limit 1;
注:

  • 存在
    可以更好地优化。(但是你的版本已经很旧了。)
  • 子字符串
    妨碍了索引的使用
  • 子字符串
    检查似乎没有用
  • codice
    必须是
    VARCHAR
    ,否则像
    这样的
    会有问题

请提供
SHOW CREATE TABLE
EXPLAIN SELECT…

索引在使用
之类的
和/或基于函数的谓词的查询中无效。在旧服务器和新服务器
子字符串上显示
EXPLAIN SELECT…
的输出(codice,9)介于“0000001”和“9999999”之间
——不要在函数中隐藏列;它防止使用索引。由于该子句没有添加任何有用的内容,所以请将其全部删除。您可能遇到了Oracle optimizer比MariaDB做得更好的特定情况。让我们看看
EXPLAIN SELECT…
。@gurvindersingh-
INDEX(codice)
可用于此“范围”:
codice类似于'1201%'
。codice是一个varchar(20),具有多个长度值和0个前导。(es:2000512,001244512011101211000000001)@user2380825你能试试我的查询,让我知道它是如何工作的(如果它不符合解释所说的)我的查询与Rick James的查询是等效的,只是他省略了
子字符串…介于
位之间(你可能需要也可能不需要;我假设它是这样保留的)他用的是notexists,而我用的是等价的左JOIN+,其中。。。是空的,这对我来说总是更快。我只在有多个这样的子句和多个一对多关系的情况下使用EXISTS/NOT EXISTS。您好,您的查询比我的快,在MariaDB上12秒,但比我的查询慢得多MySql@user2380825解释说什么?可能会有帮助的事情(取决于索引出错的位置):使其
选择“直接连接…”
或在
clfoco a
和/或
clfoco b
之后添加
使用索引(什么是索引名)
。。。这很有趣。对于3个
选择
解释中的2行。还请提供
显示警告的输出
解释扩展选择…(EXPLAIN EXTENDED SELECT…)之后立即执行我怀疑有一个重要的查询重写正在进行。同时,我的公式是否“正确”且更快?您的查询是错误的(但非常快),结果是12010001,而它应该是1201100000001。我需要在一个编号为121010、121100、121200、1212000000000001的表中找到类似121xxxyyyyyyyyyyyyy的数字的累进形式(前8个数字是“tipology”,下一个是用户ID。解释扩展选择…;显示警告;使用PhpMyadmin在同一查询中完成。找不到行。#Rick James-将您的查询稍作更改为
SELECT a.codice+1 as START FROM
clfoco`a,其中codice类似于'1201\%'和(substring(a.codice,9)介于'0000001'和'999999'之间)并且不存在(从
clfoco
中选择*,其中密码类似于“1201”;(子字符串(a.codice,9)介于“0000001”和“999999”之间),密码=a.codice+1)限制1`
SELECT  a.codice+1 AS START
    FROM  `clfoco` a
    WHERE codice LIKE '1201__%' 
      AND(substring(b.codice,9) between '0000001' and '9999999')
      AND NOT EXISTS (
                SELECT *
                FROM  `clfoco`
                WHERE codice LIKE '1201__%' 
                  AND (substring(b.codice,9) between '0000001' and '9999999')
                  AND codice = a.codice+1 )
    LIMIT 1;
id|select_type       |table |type |possible_keys|key    |key_len|ref |rows  |filtered|Extra
1 |PRIMARY           |a     |range|PRIMARY      |PRIMARY|62     |NULL|24549 |100.00  |Using where; Using index
2 |DEPENDENT SUBQUERY|clfoco|range|PRIMARY      |PRIMARY|62     |NULL|24549 |100.00  |Range checked for each record (index map: 0x1)
select a.codice+1 as codice
from clfoco a
left join clfoco b
    on b.codice=a.codice+1
    and (substring(b.codice,9) between '0000001' and '9999999')
    and b.codice like '1201__%'
where b.codice is null
and (substring(a.codice,9) between '0000001' and '9999999')
and a.codice like '1201__%'
limit 1;
select a.codice+1 as codice
from clfoco a
left join clfoco b on b.codice=a.codice+1
where b.codice is null
and (substring(a.codice,9) between '0000001' and '9999999')
and a.codice like '1201__%'
and (substring(a.codice+1,9) between '0000001' and '9999999')
and a.codice+1 like '1201__%'
limit 1;
SELECT  a.codice+1 AS START
    FROM  `clfoco` a
    WHERE codice LIKE '1201__%'
      AND NOT EXISTS (
                SELECT *
                FROM  `clfoco`
                WHERE codice LIKE '1201__%'
                  AND codice = a.codice+1 )
    LIMIT 1;