我在2台服务器上拥有相同的数据库。
服务器1(云服务器4 GB RAM)
MySQL变量= https://pastebin.com/raw/jENsXnsK
这是一个云服务器(来自rackspace的托管MySQL云实例),具有4 GB的RAM。
当我执行查询时,它有多个JOINS,它在
中执行150 rows in set (0.61 sec)
服务器2(专用32 GB RAM)
MySQL变量= https://pastebin.com/raw/sYdBhp4p
这是一个新的专用服务器,具有32 GB的内存。尚未投入生产,我们正在尝试将云服务器移至专用,因为我们获得了更多的CPU / RAM。
将数据库从云服务器复制到这个新的专用,但相同的查询需要更多时间。
150 rows in set (21.32 sec)
这比慢了大约40倍。
专用
上的free -m结果[root@server1 ~]# free -m
total used free shared buff/cache available
Mem: 31797 2700 23182 96 5914 28569
Swap: 16381 0 16381
[root@server1 ~]#
在云中没有ssh访问权限,只需像Amazon RDS那样访问MySQL。
编辑1:
我将join_buffer_size从默认值131072更改为2M,这使得查询在专用服务器上执行得更快。
150行(1.84秒)
仍然比使用4GB RAM的服务器慢约3倍。
(来自link + 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)
尽可能将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
。