2017-10-11 91 views
0

我在2臺服務器上有相同的數據庫。MySQL查詢在新服務器上佔用太多時間

服務器1(雲服務器4 GB RAM)

MySQL的變量= https://pastebin.com/raw/jENsXnsK

這是雲服務器(管理從Rackspace公司的MySQL雲實例)與4 GB的RAM。

當我執行查詢時,它具有多個連接,它是在

150 rows in set (0.61 sec) 

服務器2(專用32 GB RAM)

MySQL的變量執行= https://pastebin.com/raw/sYdBhp4p

這是一個32 GB RAM的新型專用服務器。尚未投入生產,我們正試圖將雲服務器遷移到專用設備,因爲我們獲得了更多的CPU/RAM。

從雲服務器複製到這個新的專用數據庫,但相同的查詢需要更多的時間。

150 rows in set (21.32 sec) 

這就像大約40倍慢一樣。

自由-m結果在專用

[[email protected] ~]# free -m 
       total  used  free  shared buff/cache available 
Mem:   31797  2700  23182   96  5914  28569 
Swap:   16381   0  16381 
[[email protected] ~]# 

在雲沒有SSH訪問,就像亞馬遜RDS MySQL的訪問。

編輯1:

我join_buffer_size改變從默認的131072至2M,即由查詢執行得更快專用服務器上。在集

150行(1.84秒)

仍然是大約比具有4GB RAM服務器較慢3X倍。

(從鏈接+ prettyprint)

SELECT nr.*, p.*, e.*, 
    (
     SELECT cityname as cityname 
      FROM city_type AS ct 
      where ct.id = p.city_type 
    ) as cityname, 
    (
     SELECT city_id as city_id 
      FROM tbl_suburb AS ts 
      where ts.id = e.tbl_suburb_id 
    ) as suburb_city_id, 
    (
     SELECT suburb_name 
      FROM tbl_suburb AS ts 
      where ts.id = e.tbl_suburb_id 
    ) as suburb_name, 
    (
     SELECT kilometers as km 
      FROM tbl_suburb AS tskm 
      where tskm.id = e.tbl_suburb_id 
    ) as suburb_kilometers 
    FROM new_registrations AS nr 
    INNER JOIN tbl_admin_registrations AS tar ON tar.registration_id = nr.id 
    INNER JOIN tbl_admin_properties AS tap ON tap.admin_id = tar.admin_id 
    INNER JOIN (tbl_properties AS p 
      LEFT JOIN tbl_room_types rt ON (rt.tbl_property_id = p.id) 
       ) ON p.id = tap.property_id 
    INNER JOIN tbl_expansions AS e ON e.property_id = tap.property_id 
    WHERE p.expansion = '1' 
     AND p.status = '2' 
     AND nr.country = 1 
     AND nr.id NOT IN(203, 204) 
     AND (nr.deleted = 'n' 
       OR nr.deleted IS NULL 
      ) 
     AND e.id IN (
     SELECT te.id as expansion_id 
      FROM tbl_suburb AS ts2 
      INNER JOIN tbl_expansions as te ON te.tbl_suburb_id IN (
       SELECT id 
        FROM tbl_suburb 
        WHERE city_id IN (
         SELECT id 
          FROM city_type 
          WHERE country_id = '1')) 
         )AND (
        (rt.week4 > 350 AND rt.week4 <= 5250) 
       OR (rt.week3 > 350 AND rt.week3 <= 5250) 
       OR (rt.week2 > 350 AND rt.week2 <= 5250) 
       OR (rt.week1 > 350 AND rt.week1 <= 5250)) 
    GROUP BY nr.id; 
+0

你解釋相比,對於相同的查詢計劃?解釋計劃是尋求查詢性能的第一項。 –

+0

@已使用已經我不想改變查詢,即使它會加快,因爲我不是應用程序的開發人員。我只需要在新服務器上運行相同的速度。這是查詢的解釋。 https://pastebin.com/raw/iiWKDaD7我不確定這是否是你需要的,如果你想要一個差異結果,你能告訴sql運行嗎? – HostOnNet

+0

我問**你**是否比**有過計劃。例如,這可能會顯示缺少索引,這是一個幫助您縮小原因的建議。它根本無法幫助我。 –

回答

0
  • 打開IN (SELECT ...)JOIN儘可能。我深深地看到這樣的嵌套3。

  • 嘗試獲取所需的ID 第一個,然後連接到其他表。這樣可以避免JOIN + GROUP BY的「爆炸 - 內爆」成本。

  • 'n'IS NULL之間挑選deleted。任何使用OR都是潛在的低效率。

  • week1..week4:在列中顯示數組通常是個壞主意。在這種情況下,它會導致不可優化的OR

  • join_buffer_size太小。但是JOIN緩衝區是解決上面提到的一些問題的一個障礙。

  • 所有的JOIN都可以使用索引嗎? (這是不是從一個EXPLAIN明顯。提供SHOW CREATE TABLEs,請。)