Было бы полезно, если Вы могли бы включать видеокарту своего компьютера. Вы способный выбрать 'безопасный' режим в личинке и сделать, sudo Кв. - получает обновление & & склонные sudo - получают обновление в терминале. Можно также попробовать это, когда Вы опускаетесь до терминала путем нажатия ctrl+alt+f1 и регистрируетесь там.
MySQL
оптимизирует ваш 1
прочь.
Я только что выполнил этот запрос в своей тестовой базе данных:
EXPLAIN EXTENDED
SELECT *
FROM t_source
WHERE 1 AND id < 100
, и он дал мне следующее ] description
:
select `test`.`t_source`.`id` AS `id`,`test`.`t_source`.`value` AS `value`,`test`.`t_source`.`val` AS `val`,`test`.`t_source`.`nid` AS `nid` from `test`.`t_source` where (`test`.`t_source`.`id` < 100)
Как видите, нет 1
вообще.
Документация по оптимизации раздела WHERE
в MySQL
] упоминает это:
Постоянное сворачивание:
(a b> 5 И b = c И a = 5
Удаление постоянного условия (необходимо из-за сворачивания констант):
(B> = 5 AND B = 5) OR (B = 6 AND 5 = 5) OR (B = 7 AND 5 = 6) -> B = 5 ИЛИ B = 6
Обратите внимание: 5 = 5
и 5 = 6
частей в приведенном выше примере.
. Вы можете ОБЪЯСНИТЬ свой запрос:
http://dev.mysql.com/doc /refman/5.0/en/explain.html
и посмотрите, не сделает ли он что-нибудь по-другому, в чем я сомневаюсь. Я бы использовал 1 = 1, чтобы было понятнее.
Вы можете добавить LIMIT 1000 или что-то в этом роде, когда параметры не используются и таблица становится больше, вы действительно хотите вернуть все?
WHERE 1
- постоянное, детерминированное выражение, которое будет "оптимизировано" любым подходящим механизмом БД.
Если в выбранном вами языке есть хороший способ избежать самостоятельной сборки SQL, используйте его. Мне нравятся Python и Django, а Django ORM позволяет очень легко фильтровать результаты на основе пользовательского ввода.
Если вы привержены созданию SQL самостоятельно, обязательно очистите вводимые пользователем данные от SQL-инъекций и попробуйте инкапсулировать SQL построение в отдельном модуле от вашей логики фильтра.
Кроме того, производительность запроса не должна быть вашей заботой, пока она не станет проблемой, чего, вероятно, не будет, пока у вас не будут тысячи или миллионы строк. А когда придет время для оптимизации, добавление нескольких индексов к столбцам, используемым для WHERE и JOIN, имеет большое значение.
ДЛЯ повышения производительности используйте индексы столбцов в полях, прослушиваемых в "WHERE"
Стандартные заявления об отказе от внедрения SQL-кода здесь ...
Одна вещь, которую вы можете сделать, чтобы избежать SQL-инъекции, поскольку вы знаете, что это всего четыре параметра, - это использовать хранимую процедуру, в которую вы передаете значения для полей или NULL. Я не уверен в синтаксисе хранимой процедуры mySQL, но запрос будет сводиться к
SELECT *
FROM my_table
WHERE Field1 = ISNULL(@Field1, Field1)
AND Field2 = ISNULL(@Field2, Field2)
...
ORDRE BY ordering_fld
Мы ' Не так давно я делал что-то похожее, и мы заметили несколько вещей:
Кроме того, если у вас «всего» 4 фильтра, вы можете создать вверх хранимой процедуры и передать нулевые значения и проверить их. (точно так же, как предлагалось тем временем n8wrl)
Это будет работать - некоторые соображения:
О динамически построенном SQL в целом, некоторых базах данных (Oracle по крайней мере ) будет кэшировать планы выполнения для запросов, поэтому, если вы в конечном итоге будете выполнять один и тот же запрос много раз, ему не придется полностью начинать с нуля. Если вы используете динамически построенный SQL, вы каждый раз создаете другой запрос, поэтому для базы данных он будет выглядеть как 100 разных запросов вместо 100 запусков одного и того же запроса.
Возможно, вам просто нужно измерить производительность, чтобы найти если он работает достаточно хорошо для вас.
Вам нужны все столбцы? Явное указание их, вероятно, лучше, чем использование * в любом случае, потому что:
Неплохо, я не знал этого фрагмента, чтобы избавиться от вопроса "это первый фильтр 3."
Вам должно быть стыдно за свой код (^^) , он ничего не делает для производительности, так как любой механизм БД оптимизирует его.
Единственная причина, по которой я использовал WHERE 1 = 1
, - это динамический SQL; это способ упростить добавление предложений WHERE
с помощью AND ...
. В противном случае я бы не включил это в свой SQL - он ничего не делает, чтобы повлиять на запрос в целом, потому что он всегда оценивается как истинный и не попадает в задействованные таблицы, поэтому нет никаких поисков по индексу или сканирований таблиц на основе это.
Я не могу говорить о том, как MySQL обрабатывает необязательные критерии, но я знаю, что используя следующее:
WHERE (@param IS NULL OR t.column = @param)
... это типичный способ обработки необязательных параметров. COALESCE и ISNULL не идеальны, потому что запрос все еще использует индексы (или, что еще хуже, сканирование таблиц) на основе контрольного значения. Приведенный мной пример не попадет в таблицу, пока не будет указано значение.
Тем не менее, мой опыт работы с Oracle (9i, 10g) показал, что он не очень хорошо обрабатывает [ WHERE (@param IS NULL OR t.column = @param)
]. Я увидел огромный прирост производительности за счет преобразования SQL в динамический и использовал переменные CONTEXT, чтобы определить, что добавить. Мое впечатление от SQL Server 2005 таково, что они обрабатываются лучше.
Обычно я делал что-то вроде этого:
for(int i=0; i<numConditions; i++) {
sql += (i == 0 ? "WHERE " : "AND ");
sql += dbFieldNames[i] + " = " + safeVariableValues[i];
}
Немного делает сгенерированный запрос очиститель.
Иногда я использую альтернативу - создать предложение where в виде массива и затем объединить их вместе:
my @wherefields;
foreach $c (@conditionfields) {
push @wherefields, "$c = ?",
}
my $sql = "select * from table";
if(@wherefields) { $sql.=" WHERE " . join (" AND ", @wherefields); }
Вышесказанное написано на perl, но в большинстве языков есть какая-то функция join .