2016-09-30 56 views
0

我们刚从MySQL 5.5.20迁移到MariaDB 5.5.50 我发现一个查询很奇怪的问题。Mariadb - 解释where条款depedns的条件顺序

此查询的工作在MySQL,但不能在MariaDB的:

SELECT 'za_faktura' AS tabulka, 
     za_faktura.id, 
     za_faktura.r_cislo, 
     za_faktura.o_za_platba, 
     za_faktura.a_vystaveni, 
     za_faktura.a_splatnost, 
     za_faktura.a_zaplaceno, 
     0   AS storno, 
     za_faktura.p_fakturovano, 
     za_faktura.p_fakturovano_mena, 
     za_faktura.p_fakturovano_dph, 
     za_faktura.p_fakturovano_dph_mena, 
     za_faktura.p_zaplaceno, 
     za_faktura.p_zaplaceno_mena, 
     za_faktura.p_zaplaceno_dph, 
     za_faktura.p_zaplaceno_dph_mena 
FROM za_faktura 
     INNER JOIN zamn_zakazky_faktury 
       ON zamn_zakazky_faktury.i_za_faktura = za_faktura.id 
WHERE zamn_zakazky_faktury.i_za_zakazka = '27580' 
     AND za_faktura.i_od = '6660' 
     AND za_faktura.i_pro = '3916' 
     AND za_faktura.p_fakturovano >= '600.00' 
     AND za_faktura.p_fakturovano_mena = 'CZK' 
     AND ((za_faktura.id = '26282' 
       AND za_faktura.p_fakturovano_mena = 'CZK' 
       AND za_faktura.p_fakturovano > '600') 
       OR (za_faktura.id = '26243' 
        AND za_faktura.p_fakturovano_mena = 'CZK' 
        AND za_faktura.p_fakturovano > '3000') 
       OR (za_faktura.id <> '26282' 
        AND za_faktura.id <> '26243')) 
ORDER BY za_faktura.p_fakturovano - '600.00' ASC 

EXPLAIN从玛丽亚EXTENDED:

id select_type table type possible_keys key key_len ref rows filtered Extra 
1 SIMPLE zamn_zakazky_faktury range PRIMARY   PRIMARY 4       NULL 4 75.00 Using where; Using index; Using temporary; Using f... 
1 SIMPLE za_faktura   eq_ref PRIMARY,i_od,i_pro PRIMARY 4 guidepraguecz.zamn_zakazky_faktury.i_za_faktura 1 100.00 Using index condition; Using where 

如果我取代最后一句话,在手术室它与MariaDB的顺序:

id select_type table type possible_keys key key_len ref rows filtered Extra 
1 SIMPLE zamn_zakazky_faktury ref PRIMARY     PRIMARY 4 const    4 100.00 Using where; Using index; Using temporary; Using filesort 
1 SIMPLE za_faktura    eq_ref PRIMARY,i_od,i_pro PRIMARY 4 guidepraguecz.zamn_zakazky_faktury.i_za_faktura 1 100.00 Using index condition; Using where 

Then ...

SELECT 'za_faktura' AS tabulka, 
     za_faktura.id, 
     za_faktura.r_cislo, 
     za_faktura.o_za_platba, 
     za_faktura.a_vystaveni, 
     za_faktura.a_splatnost, 
     za_faktura.a_zaplaceno, 
     0   AS storno, 
     za_faktura.p_fakturovano, 
     za_faktura.p_fakturovano_mena, 
     za_faktura.p_fakturovano_dph, 
     za_faktura.p_fakturovano_dph_mena, 
     za_faktura.p_zaplaceno, 
     za_faktura.p_zaplaceno_mena, 
     za_faktura.p_zaplaceno_dph, 
     za_faktura.p_zaplaceno_dph_mena 
FROM za_faktura 
     INNER JOIN zamn_zakazky_faktury 
       ON zamn_zakazky_faktury.i_za_faktura = za_faktura.id 
WHERE zamn_zakazky_faktury.i_za_zakazka = '27580' 
     AND za_faktura.i_od = '6660' 
     AND za_faktura.i_pro = '3916' 
     AND za_faktura.p_fakturovano >= '600.00' 
     AND za_faktura.p_fakturovano_mena = 'CZK' 
     AND ((za_faktura.id <> '26282' 
       AND za_faktura.id <> '26243') 
       OR (za_faktura.id = '26282' 
        AND za_faktura.p_fakturovano_mena = 'CZK' 
        AND za_faktura.p_fakturovano > '600') 
       OR (za_faktura.id = '26243' 
        AND za_faktura.p_fakturovano_mena = 'CZK' 
        AND za_faktura.p_fakturovano > '3000')) 
ORDER BY za_faktura.p_fakturovano - '600.00' ASC 

有enyone找到任何类似的奇怪问题?在配置中是否有任何解决方案等......我无法在网上找到任何解决方案。如果这是MariaDB中的一个错误,它会从MySQL切换中引发大量的联编。

感谢,

+0

很明显,两个查询不完全相同,除了两个或条件的排序。 –

+0

我无法复制这个 - 你确定数据库是一样的吗? –

回答

0

我不知道“怪问题”,反而使问题不要紧这个综合指数可能会加速他们两个:

za_faktura: INDEX(i_od, i_pro, p_fakturovano_mena, p_fakturovano) 

第3列可以以任何顺序;最后一个必须是最后一个(由于是'范围')。 More discussion

它往往是更好地避免在ORDER BY表达式:

ORDER BY za_faktura.p_fakturovano - '600.00' ASC -- change to: 
ORDER BY za_faktura.p_fakturovano ASC 

那些会给你相同的排序。前者不能使用索引。 (我无法确定我给你的索引是否会使它使用索引。)

您重新安排了只是OR,正确吗?由于OR通常不能优化,我会惊讶,如果有差异。

我们来看看两台机器上的索引。

+0

谢谢,索引加速查询,但我的问题是,第一个查询返回仅在MySQL上的一行。玛丽亚的成绩是空的。重新排列的OR的第二个返回两行上的一行。表za_faktura有大约65000行。 –

+0

请验证数据集和查询是否相同,然后用mariadb.com提交错误。 –