![](/img/trans.png)
[英]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.