SQL КАК Производительность только с подстановочным знаком (%) как значение

Оператор + является математическим оператором. Поэтому перед конкатенацией строки с использованием этого оператора компилятор должен решить, использовать ли его как математический оператор для сложения или использовать его для конкатенации строк.

Например: если вы объединяете a + b + c + d + e + f, компилятор примет решение 5 раз, поскольку есть оператор 5 +.

Производительность не рекомендуется.

Однако, если у вас есть только одна конкатенация, я не думаю, что есть большая разница с точки зрения производительности при использовании + или метода Concat ()

11
задан MPelletier 18 January 2014 в 16:27
поделиться

11 ответов

Я надеялся, что на этот вопрос найдется учебник, но похоже, что он будет сильно различаться в зависимости от типа базы данных. Большинство ответов указывало на то, что я должен запустить тест, что я и сделал.

Мое приложение в первую очередь ориентировано на базы данных Derby, MS SQL и Oracle. Поскольку дерби можно запускать встроенным и его легко настроить, я сначала проверил производительность на нем. Результаты были неожиданными. Я проверил наихудший сценарий на довольно большой таблице. Я провел тест 1000 раз и усреднил результаты.

Запрос 1:

SELECT * FROM TableName

Запрос 2 (со значениями a = "%" и b = "%"):

SELECT * FROM TableName WHERE a LIKE ? AND b LIKE ?

Среднее время запроса 1: 178 мс

Среднее время запроса 2: 181 мс

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

4
ответ дан 3 December 2019 в 03:52
поделиться

SQL Server обычно видит

WHERE City LIKE 'A%'

и обрабатывает его как

WHERE City >= 'A' AND City < 'B'

... и при необходимости с радостью использует поиск по индексу. Я говорю «обычно», потому что я видел, что в некоторых случаях это упрощение не выполняется.

Если кто-то пытается сделать:

WHERE City LIKE '%ville'

... тогда поиск по индексу будет практически невозможен.

Но кое-что просто:

WHERE City LIKE '%'

будет считаться эквивалентом:

WHERE City IS NOT NULL
12
ответ дан 3 December 2019 в 03:52
поделиться

Любая достойная СУБД должна исключить предложения LIKE '%' еще до того, как попытается выполнить запрос. Я почти уверен, что видел, как DB2 / z делал это в своих планах выполнения.

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

Но, как и во всех вопросах оптимизации, мера, не угадывай ! Администраторы баз данных существуют потому, что они постоянно настраивают СУБД на основе фактических данных (которые со временем меняются). Как минимум, вы должны рассчитать время (и получить планы выполнения) для всех вариантов с подходящими статическими данными, чтобы увидеть, есть ли разница.

Я знаю, что такие запросы, как:

select c from t where ((1 = 1) or (c = ?))

, оптимизированы для удаления всего Предложение where перед выполнением (в любом случае в DB2 и, прежде чем вы спросите,

2
ответ дан 3 December 2019 в 03:52
поделиться

Вы можете использовать любой анализ запросов, который предлагает СУБД (например, EXPLAIN для MySQL, SET SHOWPLAN_ALL ON для MS SQL) (или используйте один из другие методы ), EXPLAIN PLAN FOR для Oracle), чтобы увидеть, как будет выполняться запрос.

4
ответ дан 3 December 2019 в 03:52
поделиться

В зависимости от того, как структурирован предикат LIKE, и от области, в которой вы тестируете, может потребоваться полное сканирование таблицы. Семантически «%» может означать полное сканирование таблицы, но Sql Server выполняет все виды внутренней оптимизации запросов. Таким образом, возникает вопрос: оптимизирует ли Sql Server предикат LIKE, сформированный с помощью '%', и выбрасывает ли его из предложения WHERE?

1
ответ дан 3 December 2019 в 03:52
поделиться

Derby также предлагает инструменты для проверки фактического использованного плана запроса, так что вы можете проводить эксперименты с помощью Derby и просматривать план запроса, который Derby выбрал. Вы можете запустить Derby с -Dderby.language.logQueryPlan = true, и Derby запишет план запроса в derby.log, или вы можете использовать средство RUNTIMESTATISTICS, как описано здесь: http://db.apache.org /derby/docs/10.5/tuning/ctundepth853133.html

Я не уверен, что Дерби исключит A LIKE '%' раньше времени, но я также не думаю, что наличие этого предложения представит значительного замедления скорости выполнения.

Мне было бы очень интересно увидеть фактический результат плана запроса, который вы получаете в своей среде, с A LIKE 'и без него

2
ответ дан 3 December 2019 в 03:52
поделиться

Что делать, если в столбце есть ненулевое пустое значение? Ваш запрос, вероятно, будет соответствовать ему.

Если это запрос для реального приложения, попробуйте использовать функции бесплатного индексирования текста большинства современных баз данных sql. Проблемы с производительностью станут несущественными.

Простое выражение if если (AB) поиск ab еще (А) искать иначе B поиск б еще сказать пользователю, что они ничего не указали

- это тривиально в обслуживании и становится намного проще для понимания вместо того, чтобы делать предположения об операторе LIKE. Вы, вероятно, все равно сделаете это в пользовательском интерфейсе, когда отобразите результаты «Ваш поиск A нашел x» или «Ваш поиск AB нашел ...»

0
ответ дан 3 December 2019 в 03:52
поделиться

Один аспект, который Я думаю, что в обсуждении упускается тот факт, что OP хочет использовать подготовленный оператор. Во время подготовки оператора база данных / оптимизатор не сможет разработать упрощения, упомянутые другими, и поэтому не сможет оптимизировать подобный '%' как фактическое значение. не будет известен во время подготовки.

Следовательно:

  • при использовании подготовленных операторов, иметь четыре разных оператора (0, только a, только b, оба) и использовать соответствующий, когда необходимо
  • , посмотрите, если вы получить лучшую производительность, когда вы не t использовать подготовленный оператор, если придерживаться только одного оператора (хотя тогда было бы довольно просто не включать «пустые» условия)
1
ответ дан 3 December 2019 в 03:52
поделиться

Я не уверен в ценности использования подготовленного оператора с параметрами, которые вы описываете. Причина в том, что вы можете обмануть оптимизатор запросов, подготовив план выполнения, который будет совершенно неверным в зависимости от того, какой из параметров был «%».

Например, если оператор был подготовлен с планом выполнения с использованием индекса на столбец A, но параметр для столбца A оказался «%», возможно, вы столкнулись с низкой производительностью.

0
ответ дан 3 December 2019 в 03:52
поделиться

Какие общие использует для этого language?

Быстрая разработка приложений.

Если вы хотите знать, «почему именно Haskell?», то вам необходимо рассмотреть преимущества функциональных языков программирования (взято из http://c2.com/cgi/wiki ? Преимущества функционального программирования ):

  • Функциональные программы имеют тенденцию быть более лаконичными, чем их аналоги на ImperativeLanguage. Часто это приводит к усилению продуктивность программиста

  • FP поощряет быстрое создание прототипов. Таким образом, я думаю, что это лучшая парадигма разработки программного обеспечения для экстремальных программистов ... но что я знаю?

  • FP является модульным с точки зрения функциональности, тогда как ObjectOrientedProgramming является модульным с точки зрения различных аспектов. компоненты.

  • Возможность съесть свой торт и съесть его. Представьте, что у вас есть сложная объектно-ориентированная система обработки сообщений - каждый компонент может создавать состояние изменяется в зависимости от сообщения, а затем пересылает сообщение некоторым объекты, на которые он ссылается. Было бы слишком круто иметь возможность легко откатить каждое изменение, если какой-то объект глубоко в вызове иерархия решила, что сообщение некорректно? Как насчет истории различные состояния?

  • Многие служебные задачи сделаны для вас: деконструкция структур данных (PatternMatching), сохранение привязок переменных (LexicalScope с закрытия), строгая типизация (TypeInference), GarbageCollection, хранилище распределение, следует ли использовать коробку (указатель на значение) или распаковку (значение напрямую) представление ...

  • Безопасная многопоточность! Неизменяемые структуры данных не подвержены условиям гонки данных и, следовательно, не должны быть защищены замки. Если вы всегда выделяете новые объекты, а не деструктивно манипулируя существующими, блокировка может быть скрыта в система распределения и GarbageCollection.

Помимо этого, Haskell имеет свои собственные преимущества, такие как:

  • Ясный, интуитивно понятный синтаксис, вдохновленный математической нотацией.
  • Составление списка для создания списка на основе существующих списков.
  • Lambda выражения: создавать функции, не давая им явных имен. Так проще обрабатывать большие формулы.
  • Haskell полностью ссылочно прозрачен . Любой код, использующий ввод-вывод, должен быть отмечен как таковой. Таким образом, он побуждает вас отделить код с побочными эффектами (например, вывод текста на экран) от кода без (вычислений).
  • Ленивое вычисление - действительно приятная функция:
    • Даже если что-то обычно вызывает ошибку, оно все равно будет работать, пока вы не используете результат. Например, вы можете указать 1/0 в качестве первого элемента списка, и он все равно будет работать, если вы использовали только второй элемент.
    • Проще написать программы поиска, такие как эта ] решатель судоку , потому что он не загружает все комбинации сразу - он просто генерирует их по мере выполнения. Вы можете сделать это на других языках, но только Haskell делает это по умолчанию .

Вы можете проверить следующие ссылки:

-2
ответ дан 3 December 2019 в 03:52
поделиться

Oracle 10gR2, похоже, не выполняет специальной оптимизации для этой ситуации, но распознает, что LIKE '%' исключает нули.

create table like_test (col1)
as select cast(dbms_random.string('U',10) as varchar2(10))
from dual
connect by level <= 1000
/
insert into like_test values (null)
/
commit
/

exec dbms_stats.gather_table_stats(user,'like_test')

explain plan for
select count(*)
from   like_test
/
select plan_table_output from table(dbms_xplan.display)
/
explain plan for
select count(*)
from   like_test
where  col1 like '%'
/
select plan_table_output from table(dbms_xplan.display)
/
explain plan for
select count(*)
from   like_test
where  col1 is not null
/
select plan_table_output from table(dbms_xplan.display)
/

... давая ...

Plan hash value: 3733279756

------------------------------------------------------------------------
| Id  | Operation          | Name      | Rows  | Cost (%CPU)| Time     |
------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |           |     1 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |           |     1 |            |          |
|   2 |   TABLE ACCESS FULL| LIKE_TEST |  1001 |     3   (0)| 00:00:01 |
------------------------------------------------------------------------

. .. и ...

Plan hash value: 3733279756

--------------------------------------------------------------------------------
| Id  | Operation          | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |           |     1 |    10 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |           |     1 |    10 |            |          |
|*  2 |   TABLE ACCESS FULL| LIKE_TEST |  1000 | 10000 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("COL1" LIKE '%')

... и ...

Plan hash value: 3733279756

--------------------------------------------------------------------------------
| Id  | Operation          | Name      | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |           |     1 |    10 |     3   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |           |     1 |    10 |            |          |
|*  2 |   TABLE ACCESS FULL| LIKE_TEST |  1000 | 10000 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("COL1" IS NOT NULL)

Обратите внимание на количество элементов (строк) в строке TABLE ACCESS FULL

2
ответ дан 3 December 2019 в 03:52
поделиться
Другие вопросы по тегам:

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