1. 程式人生 > >mysql通過將or改成union來優化sql效能問題一例

mysql通過將or改成union來優化sql效能問題一例

某系統測試環境有支SQL執行時間較長,開發人員請求dba協助優化。
原SQL如下:
SELECT   g.id,
          ----省略-----
    FROM    g,
            y,
            t,
            o
   WHERE   g.ycon_id = y.id
           AND t.ycon_id = g.ycon_id
           AND o.bno = t.bno
           AND 1 = 1
           AND g.t_CODE = 'aa'
           AND (g.so_s_n = '123'
                OR t.cab_no = '456'
                OR t.detail_id IN
                        (SELECT   detail_id
                           FROM   go
                          WHERE   don = '789'))
           AND g.status IN ('a7', 'a8')
ORDER BY   1 ASC;
執行時間需要4.08秒。
執行計劃如下:
+------+--------------+--------------------+--------+-----------------------------------------------------+---------------------------+---------+------------------------+--------+------------------------------------+
| id   | select_type  | table              | type   | possible_keys                                       | key                       | key_len | ref                    | rows   | Extra                              |
+------+--------------+--------------------+--------+-----------------------------------------------------+---------------------------+---------+------------------------+--------+------------------------------------+
|    1 | PRIMARY      | g                  | ALL    | idx_ycon_id,idx_so_serial_number                    | NULL                      | NULL    | NULL                   | 206950 | Using where; Using filesort        |


......................................
上面顯示g表走全表掃描,需要訪問206950 行記錄,表結構如下:
show create table g\G
........
PRIMARY KEY (`_id`),
  UNIQUE KEY `id` (`id`),
  KEY `idx_ycon_id` (`ycon_id`),
  KEY `idx_so_serial_number` (`so_s_n`)
) ;
對上面sql,通過hint(force index)強制使用索引或強制更改表連線順序(straight_join),總會有一個表是全表掃描,而且y、t和o表的記錄數比g表要大很多。顯然,通過直接強制走索引或更改表連線順序無法達到優化目的。
檢視SQL中有兩個or連線三個條件,且三個條件的欄位都有索引,所以將or改成union,如下:
select a.* from (
SELECT   g.id,
          ----省略-----
    FROM    g,
            y,
            t,
            o
   WHERE   g.ycon_id = y.id
           AND t.ycon_id = g.ycon_id
           AND o.bno = t.bno
           AND 1 = 1
           AND g.t_CODE = 'aa'
           AND g.so_s_n = '123' AND g.status IN ('a7', 'a8')
union
SELECT   g.id,
          ----省略-----
    FROM    g,
            y,
            t,
            o
   WHERE   g.ycon_id = y.id
           AND t.ycon_id = g.ycon_id
           AND o.bno = t.bno
           AND 1 = 1
           AND g.t_CODE = 'aa'
           AND  t.cab_no = '456' AND g.status IN ('a7', 'a8')
union
SELECT   g.id,
          ----省略-----
    FROM    g,
            y,
            t,
            o
   WHERE   g.ycon_id = y.id
           AND t.ycon_id = g.ycon_id
           AND o.bno = t.bno
           AND 1 = 1
           AND g.t_CODE = 'aa'
           AND  t.detail_id IN
                        (SELECT   detail_id
                           FROM   go
                          WHERE   don = '789') AND g.status IN ('a7', 'a8') )a
order by a.id asc;
執行時間變為0.01秒,執行計劃略。
總結:mysql的sql優化有時需要通過改寫sql來優化,通過將or改成union,改變sql執行計劃,從而達到提升SQL效能,or改成union提升效能的前提是:or連線的各條件欄位要能用到索引。

相關推薦

mysql通過orunion優化sql效能問題

某系統測試環境有支SQL執行時間較長,開發人員請求dba協助優化。 原SQL如下: SELECT   g.id,           ----省略-----     FROM    g,             y,             t,             o

結合innodb的B+樹索引優化sql查詢

先上表結構: CREATE TABLE `quote_xxxxx` ( `instrument_id` varchar(20) NOT NULL, `time_type` varchar(20)

Case:MySQL使用left join的時候or改寫union可以提高效率

(1)優化前:使用or的時候,SQL執行時間1.47s mysql> select e.emp_no,e.first_name,d.dept_no,d.from_date,d.to_date from employees e left&n

通過陣列反序排列去除中括號,轉換json,只能適用於數組裡只有一個物件

var text='[{a:100,b:200},{c:"xx",d:"對的"}]'var text1=text.replace('[','')console.log(text1)var text2=text1.split('').reverse().join('');var

利用 mysql workbench 資料庫匯出 migration 檔案

資料庫遷徙 migration 不管是在 Laravel 框架 中還是在 Codeigniter 框架中都提到,儼然是大勢所趨?! 「廢話」雖然我在專案中很少用到,因為我做的幾個專案都是直接去改資料庫的,然後直接匯出 sql 檔案上傳 live 站或是給客戶. mysql workbench

域名https協議

在百度雲買的域名,今天打算申請下ssl證書,把域改成https訪問 首先申請ssl證書,我申請的是symantec,不要錢。 申請好後下載證書,百度雲下載的是一個crt和一個key檔案。 把證

DNS8 8 8 8有什麼利與弊

                如果DNS伺服器設定不當,可能會導致網速慢、彈窗廣告、網址打不開、開啟不是自己想要的網站、

ACCEPT非阻塞型

這個專案中寫的程式是與遠端進行SOCKET通訊,用到ACCEPT來接受遠端的連線請求,一直以來在程式裡對ACCEPT用的都是阻塞方式,接收到一個新的連線請求後,就建立一個新的執行緒處理與客戶端的通訊任務。今天由於需要實現伺服器端設定客戶端心跳包週期的功能,如果每個執行緒都去

linux用搜狗輸入法後,只能預設中文,終端英文

linux用搜狗輸入法後,只能預設中文 在安裝搜狗輸入法後,由於搜狗的預設是中文,所以不管開啟什麼,一開始輸入的都是中文,但是使用linux除了在網頁搜尋時使用中文,大多數時候,比如開啟終端都是英文命令,每次都要切換太麻煩,如何才能在每次開啟終端的時候,都預設

get請求返回的是字串,字典

(void)loginBtnClick:(id)sender{ AFHTTPRequestOperationManager *manager = [AFHTTPRequestOp

chown的許可權限制--普通使用者無法owner其他使用者,如root

[email protected]:~$ chown root motd chown: changing ownership of `motd': Operation not permitted [email protected]:~$ chown

Android Studio ActivityFragment

lse navig ive art tools ins schema 1.0 this 項目中遇到一個尷尬的問題,因為初學Android,所以用了大量Activity,但現在想要改成Fragment,但是Activity太多,感覺很頭大,研究了很久怎麽改,沒有看到合適的文章

記錄linux下通過對limits的設置優化系統性能

pgrep 目前 接下來 total 滿足 執行 獲取 linux下 第一個 系統中子進程繼承父進程的系統限制。只有以root用戶運行的進程能任意修改限制。其它進程不能增加硬限制值。這樣在一個session中登錄進程設置的硬限制值影響該session中的所有進程。 當要優化

如何pdf轉換jpg,轉換達人教你招搞定

PDF檔案和JPG圖片都是工作中比較常用的兩種格式,二者之間有著很大的區別,常常因為工作,我們需要將這兩種格式進行轉換,利用他們的優點來幫助我們完成工作。那你們知道如何將PDF轉換成JPG嗎,可能對於電腦新手都不知道吧,那不妨看看小編是怎麼轉換的吧。 1、在百度瀏覽器上下載一個PDF檔案,將檔案取名為轉換的

通過減少GL CALLS 優化渲染效能

        GL verts 表示給顯示卡繪製的頂點數          GL calls&nb

Hive 通過關閉CBO (Cost based Optimizer) 優化特定的SQL執行

Hive 自0.14.0開始,加入了一項”Cost based Optimizer”來對HQL執行計劃進行優化,這個功能通過”hive.cbo.enable”來開啟。在Hive 1.1.0之後,這個feature是預設開啟的,它可以自動優化HQL中多個JOIN的

Mysql-巧用join優化sql

0. 準備相關表來進行接下來的測試 相關建表語句請看:https://github.com/YangBaohust/my_sql user1表,取經組 +----+-----------+-----------------+---------------------------------+ |

spring cloud打包jar過程中的錯誤:NoClassDefFoundError junit4.SpringRunner

mvn spring cloud jar noclassdeffounderror 將Spring Cloud對應項目打包成Jar文件,在TESTS環節總會報錯:只要執行mvn命令時跳過TESTS環節即可:mvn -Dtest -DfailIfNoTests=false install p

動手寫一個OpenVPN的wrapper優化OpenVPN效能

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

從20秒到0.5秒:一個使用Rust語言優化Python效能的案例

導讀:Python 被很多網際網路系統廣泛使用,但在另外一方面,它也存在一些效能問題,不過 Sentry 工程師分享的在關鍵模組上用另外一門語言 Rust 來代替 Python 的情況還是比較罕見,也在 Python 圈引發了熱議,高可用架構小編將文章翻譯轉載如下。 Sentry 是一個幫助線上業務