Почему мой запрос SQL, в котором я выполняю операции MAX и ORDER BY в 2 таблицах, занимает много времени - PullRequest
0 голосов
/ 03 февраля 2020

Привет, я не очень много знаю о SQL, это определенно одно из моих слабых мест. это Oracle DB.

У меня есть 2 таблицы:

TAXI_ROUTES_TABLE:
ID  | ORIGIN   | DESTINATION | TAXI_NUMBER |  STOPS   | DAY_OF_OPERATION | INSERT_DATE
123  NORTH AVE   CAMPBELL      1552          1W;2T;4Y   01-FEB-20          27-DEC-19
124  LEMMON AVE  HENRY ST      1511          1R;5G;P3   02-FEB-20          25-DEC-19

TAXI_FARE_TABLE:
ID  | ORIGIN   | DESTINATION | TAXI_NUMBER |  STOPS   |  FARE_TYPE | FARE_TYPE_AVAIL 
123  NORTH AVE   CAMPBELL      1552          1W;2T;4Y      SENIOR        5             
123  NORTH AVE   CAMPBELL      1552          1W;2T;4Y      STUDENT       10            
123  NORTH AVE   CAMPBELL      1552          1W;2T;4Y      EMPLOYEE      10            
124  LEMMON AVE  HENRY ST      1511          1R;5G;P3      SENIOR        5             
124  LEMMON AVE  HENRY ST      1511          1R;5G;P3      STUDENT       3             
124  LEMMON AVE  HENRY ST      1511          1R;5G;P3      EMPLOYEE      10  

TAXI_ROUTES_TABLE INDEX:

STOPS, TAXI_NUMBER, DESTINATION, ORIGIN, DAY_OF_OPERATION

CREATE INDEX "TAXI_ADMIN"."IX01_TAXI_ROUTES_TABLE" ON 
"TAXI_ADMIN"."TAXI_ROUTES_TABLE" ("STOPS", "TAXI_NUMBER", "DESTINATION", 
"ORIGIN", "DAY_OF_OPERATION ") 
PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
TABLESPACE "TAXI_ADMIN" ; 

TAXI_FARE_TABLE не имеет индексов.

В этих таблицах содержатся миллионы записей . одни и те же записи находятся в обеих таблицах, просто в таблице тарифов такси они повторяются из-за типов тарифов для каждого такси.

, поэтому я пытаюсь выполнить объединение, чтобы получить все последние вставленные записи и типы тарифов для них. Так что я должен только вернуть записи, вставленные в 27-DE C -19.

Моя проблема: В моем запросе истекает ограничение по времени, оно занимает вечность. Буду очень признателен за ваше руководство по этому вопросу.

SQL:

SELECT R.ID,
       R.ORIGIN,
       R.DESTINATION,
       R.TAXI_NUMBER,
       R.STOPS,
       R.DAY_OF_OPERATION,
       R.INSERT_DATE,
       F.FARE_TYPE,
       F.FARE_TYPE_AVAIL
FROM TAXI_ADMIN.TAXI_ROUTES_TABLE R, TAXI_ADMIN.TAXI_FARE_TABLET F

WHERE INSERT_DATE = (SELECT MAX(INSERT_DATE) FROM TAXI_ADMIN.TAXI_ROUTES_TABLE)

AND R.ID = F.ID

ORDER BY R.ORIGIN, R.DESTINATION, R.DAY_OF_OPERATION;

Я не уверен, как сделать запрос быстрее. Когда я бегу без заказа довольно быстро, но заказ занимает очень много времени.

спасибо

Ответы [ 2 ]

2 голосов
/ 04 февраля 2020

Я бы порекомендовал определить идентификатор SQL для запроса, а затем использовать SQL Отчет монитора, поскольку он точно скажет вам, что такое план выполнения и где SQL тратит большую часть своего времени.

Простой способ получить отчет о мониторе SQL из SQL* Plus:

spool c:\temp\SQL_Monitor_rpt.html

SET LONG 1000000
SET LONGCHUNKSIZE 1000000
SET LINESIZE 1000
SET PAGESIZE 0
SET TRIM ON
SET TRIMSPOOL ON
SET ECHO OFF
SET FEEDBACK OFF

alter session set "_with_subquery" = optimizer;

SELECT DBMS_SQLTUNE.report_sql_monitor(
  sql_id       => '&SQLID' ,
  type         => 'HTML',
  report_level => 'ALL') AS report
FROM dual;

spool off

Кроме того, в этом случае вам, вероятно, понадобятся еще три индекса: TAXI_ADMIN.TAXI_ROUTES_TABLE.INSERT_DATE для покрытия условие подмножества и столбец идентификатора в обеих таблицах для покрытия условия объединения

1 голос
/ 04 февраля 2020

Для этого запроса (который я немного очистил):

SELECT R.ID, R.ORIGIN, R.DESTINATION, R.TAXI_NUMBER,
       R.STOPS, R.DAY_OF_OPERATION, R.INSERT_DATE,
       F.FARE_TYPE, F.FARE_TYPE_AVAIL
FROM TAXI_ADMIN.TAXI_ROUTES_TABLE R JOIN 
     TAXI_ADMIN.TAXI_FARE_TABLET F
     ON R.ID = F.ID
WHERE R.INSERT_DATE = (SELECT MAX(R2.INSERT_DATE) FROM TAXI_ADMIN.TAXI_ROUTES_TABLE R2)
ORDER BY R.ORIGIN, R.DESTINATION, R.DAY_OF_OPERATION;

Вам нужны индексы: TAXI_ROUTES_TABLE(INSERT_DATE, ID) и TAXI_FARE_TABLET(ID). Трудно устранить накладные расходы на ORDER BY. Поэтому, если данных много, это может не сильно помочь.

Если Oracle достаточно умен, то поможет расширение первого индекса до TAXI_ROUTES_TABLE(INSERT_DATE, ORIGIN, DESTINATION, DAY_OF_OPERATION, ID). Это интересная оптимизация, потому что она должна учитывать ORDER BY перед выполнением JOIN.

...