[英]Same query, different execution plan with limit and sort by. Should I change the index?
[英]Mysql 5.6 different execution plan for same query.(Java client vs terminal)
以下查询给出了GUI客户端(DB Viz)与终端之间的2种不同的执行计划,并且当我们从GUI / Java应用程序调用时花费的时间太长。
-当我们从mysql终端(直接在mysql客户端的服务器上)执行查询时,查询将在不到一秒的时间内运行。 但是,当我们从Java应用程序/ GUI客户端(如DBVIz)调用此查询时,它需要55秒。
-预期结果是<10行。
-我们正在使用Mysql 5.6。 此查询涉及的所有表都是innodb。
-问题始于5.6,我们使用的是5.0,最近又升级到5.6。
-在此查询中要注意的是,这将联接具有不同数据类型的列上的2个表。
-在基于“ finer.refernce”列进行联接的所有查询中,我们都遇到类似的问题。该列是varchar(255)列,并且它是一个通用列,用于存储整数值并将与其他表连接将具有整数ID。
-我们在finer.refernce上拥有索引idxf_reference。
-请注意,查询具有显式类型转换CAST(lb.id AS CHAR)。 也尝试了CONVERT(lb.id,CHAR(255))并且得到了相同的结果。
-GUI中使用的mysql驱动程序是mysql-connector-java-5.1.25。 还尝试了mysql-connector-java-5.1.31。 并有同样的问题。
-在GUI上进行分析显示查询在“发送数据”状态下花费了52秒。 在终端中,“发送数据”时间不到一秒
-执行计划中的重要区别在于,GUI计划不使用索引,而是使用“使用连接缓冲区(块嵌套循环)”。
-尝试使用FORCE INDEX,但仍未在GUI / Java应用程序上使用索引。
-这与BNL / BKA算法有关吗?
查询:~~~~~~
SELECT ftc.display_name,fl。* FROM lpb lb INNER JOIN精细fl ON fl.reference = CAST(lb.id AS CHAR)LEFT JOIN fintran ftc ON fl.transactioncode_id = ftc.id WHERE lb.ld_id = 12345;
该计划有3行,其中2行相同,不同之处在“ fl”表上。 下面是计划摘要。
从GUI计划:
~~~~~~~~~~~~~~
id select_type表的类型possible_keys键key_len参考行额外
1 SIMPLE fl ALL(null)(null)(null)(null)30100452使用where; 使用联接缓冲区(块嵌套循环)
从航站楼计划:
~~~~~~~~~~~~~~~~~~~
+ ---- + ------------- + ------- + -------- + ------------- ---------------- + --------------------------------------------- + --- ------ + ------------------------------ + ------ + ----- ------------------ + | id | select_type | 桌子| 类型 可能的钥匙| 关键 key_len | 参考| 行| 额外| + ---- + ------------- + ------- + -------- + ------------- ---------------- + --------------------------------------------- + --- ------ + ------------------------------ + ------ + ----- ------------------ + | 1 | 简单 fl | 参考| idxf_reference | idxf_reference | 258 | 功能| 1 | 使用索引条件
+ ---- + ------------- + ------- + -------- + ------------- ---------------- + --------------------------------------------- + --- ------ + ------------------------------ + ------ + ----- ------------------ +
我发现了执行计划更改的原因,由于在varchar列上需要utf8mb4转换,因此从GUI客户端执行查询时服务器未使用索引。 进行此转换是因为Java应用程序和GUI客户端中使用的j连接器根据服务器配置将以下2个变量设置为utf8mb4( http://dev.mysql.com/doc/relnotes/connector-j/en/news -5-1-13.html )。
character_set_client character_set_connection
桌子在latin1中。 但是,终端客户端未使用j连接器,并且为上述2个变量保留了latin1。
我们如何解决?
J连接器根据服务器配置确定上述值,因此我们从服务器my.conf中删除了下面的2,
默认字符集= utf8字符集服务器= utf8
删除此选项后,默认情况下将值设置为latin1并解决了问题。 希望将来有人遇到同样的问题时对您有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.