Общие правила для упрощения SQL-операторов

Частные члены доступны только внутри тела класса или структуры, в которой они объявлены.

Внутренние типы или элементы доступны только внутри файлов в одной сборке

65
задан Roman C 16 March 2016 в 12:57
поделиться

6 ответов

Я бы подумал о передаче ваших идентификаторов в виде XML-строки, а затем вы могли бы разрезать XML во временную таблицу для объединения, или вы также могли бы запросить XML напрямую, используя SP_XML_PREPAREDOCUMENT и OPENXML .

SELECT  TO_CHAR(SUM(xac_amount * rte_rate), 'FM999G999G999G999G999G999D999999')
FROM    t_transaction x
JOIN    t_rate r
ON      (rte_currency, rte_date) IN
        (
        SELECT  xac_currency, MAX(rte_date)
        FROM    t_rate
        WHERE   rte_currency = xac_currency
                AND rte_date <= xac_date
        )

Этот запрос можно сильно переписать, чтобы использовать условие равенства, которое разрешает HASH JOIN вместо NESTED LOOPS :

WITH v_rate AS
        (
        SELECT  cur_id AS eff_currency, dte_date AS eff_date, rte_rate AS eff_rate
        FROM    (
                SELECT  cur_id, dte_date,
                        (
                        SELECT  MAX(rte_date)
                        FROM    t_rate ri
                        WHERE   rte_currency = cur_id
                                AND rte_date <= dte_date
                        ) AS rte_effdate
                FROM    (
                        SELECT  (
                                SELECT  MAX(rte_date)
                                FROM    t_rate
                                ) - level + 1 AS dte_date
                        FROM    dual
                        CONNECT BY
                                level <=
                                (
                                SELECT  MAX(rte_date) - MIN(rte_date)
                                FROM    t_rate
                                )
                        ) v_date,
                        (
                        SELECT  1 AS cur_id
                        FROM    dual
                        UNION ALL
                        SELECT  2 AS cur_id
                        FROM    dual
                        ) v_currency
                ) v_eff
        LEFT JOIN
                t_rate
        ON      rte_currency = cur_id
                AND rte_date = rte_effdate
        )
SELECT  TO_CHAR(SUM(xac_amount * eff_rate), 'FM999G999G999G999G999G999D999999')
FROM    (
        SELECT  xac_currency, TRUNC(xac_date) AS xac_date, SUM(xac_amount) AS xac_amount, COUNT(*) AS cnt
        FROM    t_transaction x
        GROUP BY
                xac_currency, TRUNC(xac_date)
        )
JOIN    v_rate
ON      eff_currency = xac_currency
        AND eff_date = xac_date

Несмотря на то, что последний запрос является чертовски громоздким, последний запрос является в 6 раз быстрее.

Основная идея здесь заключается в замене <= на = , что требует создания календарной таблицы в памяти. к ПРИСОЕДИНЯЙТЕСЬ к с.

61
ответ дан 24 November 2019 в 15:29
поделиться

Вот несколько примеров из работы с Oracle 8 и 9 (конечно, иногда обратное может сделать запрос проще или быстрее):

Скобки можно удалить, если они не используются для переопределить приоритет оператора. Простой пример: все логические операторы в предложении where одинаковы: where ((a или b) или c) эквивалентно , где a или b или c .

Подзапрос часто (если не всегда) может быть объединен с основным запросом для его упрощения. По моему опыту, это часто значительно повышает производительность:

select foo.a,
       bar.a
  from foomatic  foo,
       bartastic bar
 where foo.id = bar.id and
       bar.id = (
         select ban.id
           from bantabulous ban
          where ban.bandana = 42
       )
;

эквивалентно

select foo.a,
       bar.a
  from foomatic    foo,
       bartastic   bar,
       bantabulous ban
 where foo.id = bar.id and
       bar.id = ban.id and
       ban.bandana = 42
;

Использование ANSI-объединений отделяет много логики «обезьяны кода» от действительно интересных частей предложения where:

9
ответ дан 24 November 2019 в 15:29
поделиться

Мне нравится заменять все виды подзапроса запросом соединения.

Это очевидно:

SELECT  *
FROM    mytable mo
WHERE   EXISTS
        (
          SELECT  *
          FROM    othertable o
          WHERE   o.othercol = mo.col
        )

by

SELECT  mo.*
FROM    mytable mo inner join othertable o on o.othercol = mo.col

А это недооценено:

SELECT  *
FROM    mytable mo
WHERE   NOT EXISTS
        (
          SELECT  *
          FROM    othertable o
          WHERE   o.othercol = mo.col
        )

by

SELECT  mo.*
FROM    mytable mo left outer join othertable o on o.othercol = mo.col
WHERE   o.othercol is null

Это могло бы помочь СУБД выбрать хороший план выполнения в большом запросе.

5
ответ дан 24 November 2019 в 15:29
поделиться
  • Я полагаю, очевидным является поиск любых курсоров, которые можно заменить операцией на основе SQL 'Set'.
  • Следующим в моем списке является поиск любых коррелированных подзапросов, которые может быть переписан как некоррелированный запрос
  • . В длинных хранимых процедурах разбивайте отдельные операторы SQL на их собственные хранимые процедуры. Таким образом они получат собственный кэшированный план запроса.
  • Ищите транзакции, область действия которых может быть сокращена. Я регулярно нахожу внутри транзакции операторы, которые могут безопасно находиться снаружи.
  • Подвыборки часто можно переписать как прямые соединения (современные оптимизаторы умеют находить простые)

Как упоминал @Quassnoi, Оптимизатор часто делает хорошую работу. Один из способов помочь - обеспечить актуальность индексов и статистики, а также наличие подходящих индексов для вашей рабочей нагрузки запросов.

6
ответ дан 24 November 2019 в 15:29
поделиться

Учитывая природу SQL, вы обязательно должны осознавать влияние любого рефакторинга на производительность. Рефакторинг приложений SQL - хороший ресурс по рефакторингу с упором на производительность (см. Главу 5).

4
ответ дан 24 November 2019 в 15:29
поделиться

Мне нравится, что все в команде следуют набору стандартов, чтобы сделать код читаемым, поддерживаемым, понятным, моющимся и т. Д. :)

  • все используют один и тот же псевдоним
  • нет курсоры. без циклов
  • зачем даже думать о IN, если можно EXISTS
  • INDENT
  • Согласованность в стиле кодирования

здесь есть еще кое-что Каковы некоторые из ваших наиболее полезных стандартов баз данных?

5
ответ дан 24 November 2019 в 15:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: