Oracle
查看:如果不使用左連接,則忽略它?
我有一個 Web 服務,它引用了一個名為
gis_sidewalks_vw
.create table gis_sidewalks ( id number(10,0), last_edited_date date ); insert into gis_sidewalks (id, last_edited_date) values (1, TO_DATE('2019/01/01 00:00:00', 'yyyy/mm/dd hh24:mi:ss')); insert into gis_sidewalks (id, last_edited_date) values (2, TO_DATE('2019/02/01 00:00:00', 'yyyy/mm/dd hh24:mi:ss')); insert into gis_sidewalks (id, last_edited_date) values (3, TO_DATE('2019/03/01 00:00:00', 'yyyy/mm/dd hh24:mi:ss')); insert into gis_sidewalks (id, last_edited_date) values (4, TO_DATE('2019/04/01 00:00:00', 'yyyy/mm/dd hh24:mi:ss')); commit; create table maximo_assets ( id number(10,0), lastsyncdate date ); insert into maximo_assets (id, lastsyncdate) values (1, TO_DATE('2019/04/01 00:00:00', 'yyyy/mm/dd hh24:mi:ss')); insert into maximo_assets (id, lastsyncdate) values (2, TO_DATE('2019/03/01 00:00:00', 'yyyy/mm/dd hh24:mi:ss')); insert into maximo_assets (id, lastsyncdate) values (3, TO_DATE('2019/02/01 00:00:00', 'yyyy/mm/dd hh24:mi:ss')); insert into maximo_assets (id, lastsyncdate) values (4, TO_DATE('2019/01/01 00:00:00', 'yyyy/mm/dd hh24:mi:ss')); commit; create or replace view gis_sidewalks_vw as ( select s.id, s.last_edited_date as gis_last_edited_date, a.lastsyncdate as maximo_lastsyncdate, case when s.last_edited_date > a.lastsyncdate then 1 end sync_needed from gis_sidewalks s left join maximo_assets a on s.id = a.id ); select * from gis_sidewalks_vw; ID GIS_LAST_EDITED_DATE MAXIMO_LASTSYNCDATE SYNC_NEEDED ---------- -------------------- ------------------- ----------- 1 01-JAN-19 01-APR-19 2 01-FEB-19 01-MAR-19 3 01-MAR-19 01-FEB-19 1 4 01-APR-19 01-JAN-19 1
該視圖有一個左連接和一個計算列:
case when s.last_edited_date > a.lastsyncdate then 1 end sync_needed ... left join maximo_assets a
設想:
視圖和網路服務是多用途的。
目的#1:
僅提供cron任務所在的行
sync_needed = 1
(每周同步到單獨的數據庫)。目的#2:
將視圖中的所有行提供給 web 地圖(地圖一直在使用)。
問題:
maximo_assets
在目的 #1 中,加入表並生成計算列是有意義的。但是,在目的 #2 中,加入表並生成計算列是沒有意義的。
maximo_assets
不出所料,出於目的 #2,由於不必要的加入,我在 web 地圖中遇到了性能問題。
問題:
有沒有辦法設計視圖,以便在未使用連接時忽略與
maximo_assets
表的連接?例如:
select id, gis_last_edited_date --maximo_lastsyncdate --sync_needed from gis_sidewalks_vw
想想看。這種沒有進一步資訊的連接不能被跳過。即使您不從 maximo_assets 中選擇列,與其連接也可能會增加返回的行數,因為對於 gis_sidewalks 中的 1 個 ID,您可以在 maximo_assets 中擁有多個具有相同 ID 的行。
如果 ID 是唯一的(或 PK),並且您通過創建適當的約束使數據庫知道這一點,那麼上述情況不再適用,它將能夠跳過 maximo_assets 表:
alter table gis_sidewalks add primary key (id); alter table maximo_assets add primary key (id); select id, gis_last_edited_date--, --maximo_lastsyncdate, --sync_needed from gis_sidewalks_vw; ID GIS_LAST_ ---------- --------- 1 01-JAN-19 2 01-FEB-19 3 01-MAR-19 4 01-APR-19 SQL> select * from table(dbms_xplan.display_cursor); PLAN_TABLE_OUTPUT ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- SQL_ID f4p3b2huhfk5a, child number 0 ------------------------------------- select id, gis_last_edited_date--, --maximo_lastsyncdate, --sync_needed from gis_sidewalks_vw Plan hash value: 1031306697 ----------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | ----------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | | | 3 (100)| | | 1 | TABLE ACCESS FULL| GIS_SIDEWALKS | 4 | 88 | 3 (0)| 00:00:01 | ----------------------------------------------------------------------------------- Note ----- - dynamic statistics used: dynamic sampling (level=2)
您發布的子查詢的性能不會很好地擴展。
此外,多用途 SQL 是許多性能問題的根源,因此請小心處理。