2017-10-11 64 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,请。)