Измерение сложности операторов SQL - PullRequest
27 голосов
/ 28 июля 2010

Сложность методов в большинстве языков программирования может быть измерена в цикломатической сложности с помощью статических анализаторов исходного кода. Существует ли подобный показатель для измерения сложности SQL-запроса?

Достаточно просто измерить время, необходимое для возврата запроса, но что, если я просто хочу количественно оценить, насколько сложен запрос?

[Edit / Note] Хотя получение плана выполнения полезно, это не обязательно то, что я пытаюсь определить в этом случае. Я не ищу, насколько сложно серверу выполнить запрос, я ищу показатель, который показывает, насколько сложно разработчику было написать запрос, и насколько вероятно, что он содержит дефект.

[Редактировать / Примечание 2] Следует признать, что бывают случаи, когда измерение сложности бесполезно, но бывают и такие времена. Для дальнейшего обсуждения этой темы см. этот вопрос .

Ответы [ 9 ]

10 голосов
/ 28 июля 2010

Я не уверен, что получение планов запросов ответит на вопрос: планы запросов скрывают часть сложности вычислений, выполняемых с данными до того, как они возвращаются (или используются в фильтре);планы запросов требуют значимой базы данных, чтобы быть актуальными.На самом деле, сложность и продолжительность исполнения несколько противоположны;что-то вроде «Хорошо, Быстро, Дешево - Выбирай любые два».

В конечном счете, это вероятность ошибиться или не понять код, который я написал?

Что-то вроде:

  • количество таблиц раз (1
  • + 1 на выражение объединения (+1 на внешнее соединение?)
  • + 1 на предикат после WHERE или HAVING
  • + 1 на GROUP BY выражение
  • + 1 на UNION или INTERSECT
  • + 1 на вызов функции
  • + 1 наCASE выражение
  • )
10 голосов
/ 31 июля 2010

Общие показатели сложности программного обеспечения включают Цикломатическая сложность (мера сложности управляющего потока) и Сложность Холстеда (мера комплексной арифметики).

«Поток управления» в запросе SQL лучше всего связан с операторами «и» и «или» в запросе.

«Вычислительная сложность» лучше всего связана с такими операторами, как SUM или неявные СОЕДИНЕНИЯ.

Как только вы решили, как классифицировать каждую единицу синтаксиса SQL-запроса относительно того, является ли это «потоком управления» или «вычислением», вы можете напрямую вычислять цикломатические или хальстедовские меры.

То, что оптимизатор SQL делает с запросами, я считаю абсолютно неактуальным. Цель показателей сложности - определить, насколько сложно человеку понять запрос, а не то, насколько эффективно он может быть оценен.

Точно так же, то, что говорит DDL или участвуют ли представления или нет, не должно быть включено в такие меры сложности. Предположение, лежащее в основе этих метрик, заключается в том, что сложность механизма внутри используемой абстракции не интересна, когда вы просто вызываете ее, потому что, по-видимому, эта абстракция делает что-то, что хорошо понимает кодер. Вот почему меры Халстеда и Цикломатика не включают в свои подсчеты вызываемые подпрограммы, и я думаю, что вы можете привести хороший пример того, что представления и информация DDL являются теми «вызываемыми» абстрактными выражениями.

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

4 голосов
/ 23 декабря 2012

Пожалуйста, не стесняйтесь попробовать мой скрипт, который дает обзор размера хранимой процедуры, количества зависимостей объекта и количества параметров -

Расчет сложности хранимых процедур TSQL

2 голосов
/ 28 июля 2010

SQL-запросы являются декларативными, а не процедурными: они не указывают, как достичь своей цели.Движок SQL создаст процедурный план атаки, и это может быть хорошим местом для поиска сложности.Попробуйте проверить выходные данные оператора EXPLAIN (или EXPLAIN PLAN), это будет грубое описание шагов, которые механизм будет использовать для выполнения вашего запроса.

1 голос
/ 28 июля 2010

Ну, я не знаю ни одного инструмента, который бы делал такую ​​вещь, но мне кажется, что то, что усложнит запрос, будет измеряться: числом соединений, числом, где определяется число функцийчисло подзапросов число приведений к разным типам данных число операторов case количество циклов или курсоров количество шагов в транзакции

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

0 голосов
/ 09 августа 2012

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

В качестве альтернативы используйте размер запросов в байтах при сохранении в файл (следите за тем, чтобы все запросы сохранялись с использованием одинаковой кодировки символов).

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

0 голосов
/ 28 июля 2010

Хороший вопрос.Проблема в том, что для SQL-запроса, подобного:

SELECT * FROM foo;

, сложность может зависеть от того, что такое "foo", и от реализации базы данных.Для такой функции, как:

int f( int n ) {
   if ( n == 42 ) {
      return 0;
   }
   else {
      return n;
   }
}

такой зависимости нет.

Тем не менее, я думаю, что должна быть возможность придумать некоторые полезные метрики для SELECT, даже если они неочень точно, и мне будет интересно посмотреть, какие ответы это дает.

0 голосов
/ 28 июля 2010

В зависимости от вашей СУБД, могут существовать инструменты плана запроса, которые могут помочь вам проанализировать шаги, которые СУБД предпримет при получении вашего запроса.

SQL Server Management Studio Express имеет встроенный план выполнения запросов. У Pervasive PSQL есть Finder плана запросов. У DB2 есть похожие инструменты (забыл, как они называются).

0 голосов
/ 28 июля 2010

Хорошо, если вы используете SQL Server, я бы сказал, что вы должны посмотреть на стоимость запроса в плане выполнения (в частности, на стоимость поддерева).

Здесь - это ссылка на некоторые вещи, которые вы должны посмотреть в плане выполнения.

...