调整 SQL 语句性能
Tuning SQL statement performance
我有两个查询 return 相同的结果:
1.
SELECT DISTINCT
cvc.object_id
, cvc.object_name
FROM ems.ibo_sm_cvc_rfs cvc,
ems.ibo_alcatel_mse_locale poi,
ems.ibo_nbn_csa csa,
ems.ibo_sm_ean_service_sites_rfs sites,
ems.ibo_sm_ean_service_site_rfs site
WHERE poi.object_name ='testPoi'
AND csa.parent_id = poi.object_id
AND cvc.csa_id = csa.csa_id
AND sites.parent_id = cvc.object_id
AND site.service_site_type = 'testSite'
AND site.object_name IN (SELECT mse_chassis.object_name
FROM ems.ibo_alcatel_mse_chassis mse_chassis
WHERE mse_chassis.parent_id = poi.object_id);
2。 :
SELECT cvc.object_id,
cvc.object_name
FROM ems.ibo_sm_cvc_rfs cvc
JOIN ems.ibo_nbn_csa csa
ON cvc.csa_id = csa.csa_id
JOIN ems.ibo_sm_ean_service_sites_rfs sites
ON sites.parent_id = cvc.object_id
WHERE csa.parent_id IN (SELECT poi.object_id
FROM ems.ibo_alcatel_mse_locale poi
WHERE poi.object_id IN (SELECT csa.parent_id FROM ems.ibo_nbn_csa csa)
AND poi.object_name = 'testPoi'
AND poi.object_id IN
(SELECT mse_chassis.parent_id
FROM EMS.ibo_alcatel_mse_chassis mse_chassis
WHERE mse_chassis.object_name IN
(SELECT site.object_name
FROM EMS.ibo_sm_ean_service_site_rfs site
WHERE site.service_site_type = 'testSite')
)
);
对我来说奇怪的是第一个语句在 0.156 秒内完成,而第二个语句在 0.624 秒内完成。需要提到的是,所有 ems.* 对象都是视图,我发现基本上 where 子句中的每一列都被索引了。
如果需要,我可以放置视图模式,但我宁愿不放置,因为这是公司信息。也许一双经验丰富的眼睛可以看出这两种说法的改进
正如@Mihai 指出的那样,你的第二个查询充满了子查询,我会再更进一步微调你的第一个发布的查询,如下所示
SELECT DISTINCT
cvc.object_id
, cvc.object_name
FROM ems.ibo_sm_cvc_rfs cvc
JOIN ems.ibo_nbn_csa csa ON cvc.csa_id = csa.csa_id
JOIN ems.ibo_alcatel_mse_locale poi ON csa.parent_id = poi.object_id
JOIN ems.ibo_sm_ean_service_sites_rfs sites ON sites.parent_id = cvc.object_id
JOIN EMS.ibo_alcatel_mse_chassis mse_chassis ON mse_chassis.parent_id = poi.object_id
JOIN EMS.ibo_sm_ean_service_site_rfs site ON site.object_name = mse_chassis.object_name
WHERE poi.object_name ='testPoi'
AND site.service_site_type = 'testSite';
注意两件事:
我已将您的隐式连接语法修改为显式连接语法
我已将带有 IN
子句的最后一个子查询修改为 JOIN
语句
SELECT
cvc.object_id
, cvc.object_name
FROM ems.ibo_sm_cvc_rfs cvc,
ems.ibo_alcatel_mse_locale poi,
ems.ibo_nbn_csa csa,
ems.ibo_sm_ean_service_sites_rfs sites,
EMS.ibo_sm_ean_service_site_rfs site,
EMS.ibo_alcatel_mse_chassis mse_chassis
WHERE poi.object_name ='testPoi'
AND csa.parent_id = poi.object_id
AND cvc.csa_id = csa.csa_id
AND sites.parent_id = cvc.object_id
AND site.service_site_type = 'testSite'
AND site.object_name = mse_chassis.object_name
AND mse_chassis.parent_id = poi.object_id
GROUP BY cvc.object_id, cvc.object_name
旨在进行非常有效的松散索引扫描,添加此索引
CREATE INDEX objects_idx
ON ibo_sm_cvc_rfs (object_id, object_name);
我有两个查询 return 相同的结果:
1.
SELECT DISTINCT
cvc.object_id
, cvc.object_name
FROM ems.ibo_sm_cvc_rfs cvc,
ems.ibo_alcatel_mse_locale poi,
ems.ibo_nbn_csa csa,
ems.ibo_sm_ean_service_sites_rfs sites,
ems.ibo_sm_ean_service_site_rfs site
WHERE poi.object_name ='testPoi'
AND csa.parent_id = poi.object_id
AND cvc.csa_id = csa.csa_id
AND sites.parent_id = cvc.object_id
AND site.service_site_type = 'testSite'
AND site.object_name IN (SELECT mse_chassis.object_name
FROM ems.ibo_alcatel_mse_chassis mse_chassis
WHERE mse_chassis.parent_id = poi.object_id);
2。 :
SELECT cvc.object_id,
cvc.object_name
FROM ems.ibo_sm_cvc_rfs cvc
JOIN ems.ibo_nbn_csa csa
ON cvc.csa_id = csa.csa_id
JOIN ems.ibo_sm_ean_service_sites_rfs sites
ON sites.parent_id = cvc.object_id
WHERE csa.parent_id IN (SELECT poi.object_id
FROM ems.ibo_alcatel_mse_locale poi
WHERE poi.object_id IN (SELECT csa.parent_id FROM ems.ibo_nbn_csa csa)
AND poi.object_name = 'testPoi'
AND poi.object_id IN
(SELECT mse_chassis.parent_id
FROM EMS.ibo_alcatel_mse_chassis mse_chassis
WHERE mse_chassis.object_name IN
(SELECT site.object_name
FROM EMS.ibo_sm_ean_service_site_rfs site
WHERE site.service_site_type = 'testSite')
)
);
对我来说奇怪的是第一个语句在 0.156 秒内完成,而第二个语句在 0.624 秒内完成。需要提到的是,所有 ems.* 对象都是视图,我发现基本上 where 子句中的每一列都被索引了。 如果需要,我可以放置视图模式,但我宁愿不放置,因为这是公司信息。也许一双经验丰富的眼睛可以看出这两种说法的改进
正如@Mihai 指出的那样,你的第二个查询充满了子查询,我会再更进一步微调你的第一个发布的查询,如下所示
SELECT DISTINCT
cvc.object_id
, cvc.object_name
FROM ems.ibo_sm_cvc_rfs cvc
JOIN ems.ibo_nbn_csa csa ON cvc.csa_id = csa.csa_id
JOIN ems.ibo_alcatel_mse_locale poi ON csa.parent_id = poi.object_id
JOIN ems.ibo_sm_ean_service_sites_rfs sites ON sites.parent_id = cvc.object_id
JOIN EMS.ibo_alcatel_mse_chassis mse_chassis ON mse_chassis.parent_id = poi.object_id
JOIN EMS.ibo_sm_ean_service_site_rfs site ON site.object_name = mse_chassis.object_name
WHERE poi.object_name ='testPoi'
AND site.service_site_type = 'testSite';
注意两件事:
我已将您的隐式连接语法修改为显式连接语法
我已将带有
IN
子句的最后一个子查询修改为JOIN
语句
SELECT
cvc.object_id
, cvc.object_name
FROM ems.ibo_sm_cvc_rfs cvc,
ems.ibo_alcatel_mse_locale poi,
ems.ibo_nbn_csa csa,
ems.ibo_sm_ean_service_sites_rfs sites,
EMS.ibo_sm_ean_service_site_rfs site,
EMS.ibo_alcatel_mse_chassis mse_chassis
WHERE poi.object_name ='testPoi'
AND csa.parent_id = poi.object_id
AND cvc.csa_id = csa.csa_id
AND sites.parent_id = cvc.object_id
AND site.service_site_type = 'testSite'
AND site.object_name = mse_chassis.object_name
AND mse_chassis.parent_id = poi.object_id
GROUP BY cvc.object_id, cvc.object_name
旨在进行非常有效的松散索引扫描,添加此索引
CREATE INDEX objects_idx
ON ibo_sm_cvc_rfs (object_id, object_name);