Оператор + является математическим оператором. Поэтому перед конкатенацией строки с использованием этого оператора компилятор должен решить, использовать ли его как математический оператор для сложения или использовать его для конкатенации строк.
Например: если вы объединяете a + b + c + d + e + f, компилятор примет решение 5 раз, поскольку есть оператор 5 +.
Производительность не рекомендуется.
Однако, если у вас есть только одна конкатенация, я не думаю, что есть большая разница с точки зрения производительности при использовании + или метода Concat ()
Я надеялся, что на этот вопрос найдется учебник, но похоже, что он будет сильно различаться в зависимости от типа базы данных. Большинство ответов указывало на то, что я должен запустить тест, что я и сделал.
Мое приложение в первую очередь ориентировано на базы данных 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 почти одинакова между двумя запросами.
SQL Server обычно видит
WHERE City LIKE 'A%'
и обрабатывает его как
WHERE City >= 'A' AND City < 'B'
... и при необходимости с радостью использует поиск по индексу. Я говорю «обычно», потому что я видел, что в некоторых случаях это упрощение не выполняется.
Если кто-то пытается сделать:
WHERE City LIKE '%ville'
... тогда поиск по индексу будет практически невозможен.
Но кое-что просто:
WHERE City LIKE '%'
будет считаться эквивалентом:
WHERE City IS NOT NULL
Любая достойная СУБД должна исключить предложения LIKE '%'
еще до того, как попытается выполнить запрос. Я почти уверен, что видел, как DB2 / z делал это в своих планах выполнения.
Подготовленный оператор не должен иметь значения, поскольку он должен быть преобразован в реальный SQL, прежде чем он попадет в механизм выполнения.
Но, как и во всех вопросах оптимизации, мера, не угадывай ! Администраторы баз данных существуют потому, что они постоянно настраивают СУБД на основе фактических данных (которые со временем меняются). Как минимум, вы должны рассчитать время (и получить планы выполнения) для всех вариантов с подходящими статическими данными, чтобы увидеть, есть ли разница.
Я знаю, что такие запросы, как:
select c from t where ((1 = 1) or (c = ?))
, оптимизированы для удаления всего Предложение where перед выполнением (в любом случае в DB2 и, прежде чем вы спросите,
Вы можете использовать любой анализ запросов, который предлагает СУБД (например, EXPLAIN
для MySQL, SET SHOWPLAN_ALL ON
для MS SQL) (или используйте один из другие методы ), EXPLAIN PLAN FOR
для Oracle), чтобы увидеть, как будет выполняться запрос.
В зависимости от того, как структурирован предикат LIKE, и от области, в которой вы тестируете, может потребоваться полное сканирование таблицы. Семантически «%» может означать полное сканирование таблицы, но Sql Server выполняет все виды внутренней оптимизации запросов. Таким образом, возникает вопрос: оптимизирует ли Sql Server предикат LIKE, сформированный с помощью '%', и выбрасывает ли его из предложения WHERE?
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 'и без него
Что делать, если в столбце есть ненулевое пустое значение? Ваш запрос, вероятно, будет соответствовать ему.
Если это запрос для реального приложения, попробуйте использовать функции бесплатного индексирования текста большинства современных баз данных sql. Проблемы с производительностью станут несущественными.
Простое выражение if если (AB) поиск ab еще (А) искать иначе B поиск б еще сказать пользователю, что они ничего не указали
- это тривиально в обслуживании и становится намного проще для понимания вместо того, чтобы делать предположения об операторе LIKE. Вы, вероятно, все равно сделаете это в пользовательском интерфейсе, когда отобразите результаты «Ваш поиск A нашел x» или «Ваш поиск AB нашел ...»
Один аспект, который Я думаю, что в обсуждении упускается тот факт, что OP хочет использовать подготовленный оператор. Во время подготовки оператора база данных / оптимизатор не сможет разработать упрощения, упомянутые другими, и поэтому не сможет оптимизировать подобный '%'
как фактическое значение. не будет известен во время подготовки.
Следовательно:
Я не уверен в ценности использования подготовленного оператора с параметрами, которые вы описываете. Причина в том, что вы можете обмануть оптимизатор запросов, подготовив план выполнения, который будет совершенно неверным в зависимости от того, какой из параметров был «%».
Например, если оператор был подготовлен с планом выполнения с использованием индекса на столбец A, но параметр для столбца A оказался «%», возможно, вы столкнулись с низкой производительностью.
Какие общие использует для этого language?
Быстрая разработка приложений.
Если вы хотите знать, «почему именно Haskell?», то вам необходимо рассмотреть преимущества функциональных языков программирования (взято из http://c2.com/cgi/wiki ? Преимущества функционального программирования ):
Функциональные программы имеют тенденцию быть более лаконичными, чем их аналоги на ImperativeLanguage. Часто это приводит к усилению продуктивность программиста
FP поощряет быстрое создание прототипов. Таким образом, я думаю, что это лучшая парадигма разработки программного обеспечения для экстремальных программистов ... но что я знаю?
FP является модульным с точки зрения функциональности, тогда как ObjectOrientedProgramming является модульным с точки зрения различных аспектов. компоненты.
Возможность съесть свой торт и съесть его. Представьте, что у вас есть сложная объектно-ориентированная система обработки сообщений - каждый компонент может создавать состояние изменяется в зависимости от сообщения, а затем пересылает сообщение некоторым объекты, на которые он ссылается. Было бы слишком круто иметь возможность легко откатить каждое изменение, если какой-то объект глубоко в вызове иерархия решила, что сообщение некорректно? Как насчет истории различные состояния?
Многие служебные задачи сделаны для вас: деконструкция структур данных (PatternMatching), сохранение привязок переменных (LexicalScope с закрытия), строгая типизация (TypeInference), GarbageCollection, хранилище распределение, следует ли использовать коробку (указатель на значение) или распаковку (значение напрямую) представление ...
Безопасная многопоточность! Неизменяемые структуры данных не подвержены условиям гонки данных и, следовательно, не должны быть защищены замки. Если вы всегда выделяете новые объекты, а не деструктивно манипулируя существующими, блокировка может быть скрыта в система распределения и GarbageCollection.
Помимо этого, Haskell имеет свои собственные преимущества, такие как:
1/0
в качестве первого элемента списка, и он все равно будет работать, если вы использовали только второй элемент. Вы можете проверить следующие ссылки:
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