Как плохо мой запрос?

Было бы полезно, если Вы могли бы включать видеокарту своего компьютера. Вы способный выбрать 'безопасный' режим в личинке и сделать, sudo Кв. - получает обновление & & склонные sudo - получают обновление в терминале. Можно также попробовать это, когда Вы опускаетесь до терминала путем нажатия ctrl+alt+f1 и регистрируетесь там.

27
задан Evernoob 22 September 2009 в 15:51
поделиться

12 ответов

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 частей в приведенном выше примере.

37
ответ дан 28 November 2019 в 04:33
поделиться

. Вы можете ОБЪЯСНИТЬ свой запрос:
http://dev.mysql.com/doc /refman/5.0/en/explain.html

и посмотрите, не сделает ли он что-нибудь по-другому, в чем я сомневаюсь. Я бы использовал 1 = 1, чтобы было понятнее.

Вы можете добавить LIMIT 1000 или что-то в этом роде, когда параметры не используются и таблица становится больше, вы действительно хотите вернуть все?

8
ответ дан 28 November 2019 в 04:33
поделиться

WHERE 1 - постоянное, детерминированное выражение, которое будет "оптимизировано" любым подходящим механизмом БД.

5
ответ дан 28 November 2019 в 04:33
поделиться

Если в выбранном вами языке есть хороший способ избежать самостоятельной сборки SQL, используйте его. Мне нравятся Python и Django, а Django ORM позволяет очень легко фильтровать результаты на основе пользовательского ввода.

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

Кроме того, производительность запроса не должна быть вашей заботой, пока она не станет проблемой, чего, вероятно, не будет, пока у вас не будут тысячи или миллионы строк. А когда придет время для оптимизации, добавление нескольких индексов к столбцам, используемым для WHERE и JOIN, имеет большое значение.

4
ответ дан 28 November 2019 в 04:33
поделиться

ДЛЯ повышения производительности используйте индексы столбцов в полях, прослушиваемых в "WHERE"

2
ответ дан 28 November 2019 в 04:33
поделиться

Стандартные заявления об отказе от внедрения SQL-кода здесь ...

Одна вещь, которую вы можете сделать, чтобы избежать SQL-инъекции, поскольку вы знаете, что это всего четыре параметра, - это использовать хранимую процедуру, в которую вы передаете значения для полей или NULL. Я не уверен в синтаксисе хранимой процедуры mySQL, но запрос будет сводиться к

SELECT *
  FROM my_table
 WHERE Field1 = ISNULL(@Field1, Field1)
   AND Field2 = ISNULL(@Field2, Field2)
   ...
 ORDRE BY ordering_fld
2
ответ дан 28 November 2019 в 04:33
поделиться

Мы ' Не так давно я делал что-то похожее, и мы заметили несколько вещей:

  • Настройка индексов для столбцов, которые мы (возможно) фильтруем, улучшенная производительность
  • Часть WHERE 1 можно опустить полностью, если фильтры не используются. (не уверен, что это применимо к вашему случаю) Не имеет значения, но «кажется» правильным.
  • Не следует забывать SQL-инъекцию

Кроме того, если у вас «всего» 4 фильтра, вы можете создать вверх хранимой процедуры и передать нулевые значения и проверить их. (точно так же, как предлагалось тем временем n8wrl)

2
ответ дан 28 November 2019 в 04:33
поделиться

Это будет работать - некоторые соображения:

О динамически построенном SQL в целом, некоторых базах данных (Oracle по крайней мере ) будет кэшировать планы выполнения для запросов, поэтому, если вы в конечном итоге будете выполнять один и тот же запрос много раз, ему не придется полностью начинать с нуля. Если вы используете динамически построенный SQL, вы каждый раз создаете другой запрос, поэтому для базы данных он будет выглядеть как 100 разных запросов вместо 100 запусков одного и того же запроса.

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

Вам нужны все столбцы? Явное указание их, вероятно, лучше, чем использование * в любом случае, потому что:

  • Вы можете визуально увидеть, какие столбцы возвращаются
  • Если вы добавите или удалите столбцы в таблице позже, они не изменят ваш интерфейс
2
ответ дан 28 November 2019 в 04:33
поделиться

Неплохо, я не знал этого фрагмента, чтобы избавиться от вопроса "это первый фильтр 3."

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

2
ответ дан 28 November 2019 в 04:33
поделиться

Единственная причина, по которой я использовал 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 таково, что они обрабатываются лучше.

2
ответ дан 28 November 2019 в 04:33
поделиться

Обычно я делал что-то вроде этого:

for(int i=0; i<numConditions; i++) {
  sql += (i == 0 ? "WHERE " : "AND ");
  sql += dbFieldNames[i] + " = " + safeVariableValues[i];
}

Немного делает сгенерированный запрос очиститель.

2
ответ дан 28 November 2019 в 04:33
поделиться

Иногда я использую альтернативу - создать предложение where в виде массива и затем объединить их вместе:

my @wherefields;
foreach $c (@conditionfields) {
  push @wherefields, "$c = ?",
}

my $sql = "select * from table";
if(@wherefields) { $sql.=" WHERE " . join (" AND ", @wherefields); }

Вышесказанное написано на perl, но в большинстве языков есть какая-то функция join .

2
ответ дан 28 November 2019 в 04:33
поделиться
Другие вопросы по тегам:

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