простой SQL-запрос - PullRequest
       8

простой SQL-запрос

1 голос
/ 14 июля 2009

который быстрее

select * from parents p
inner join children c on p.id = c.pid
where p.x = 2

OR

select * from 
(select * from parents where p.x = 2)
p
inner join children c on p.id = c.pid
where p.x = 2

Ответы [ 6 ]

6 голосов
/ 14 июля 2009

В MySQL первый быстрее:

SELECT  *
FROM    parents p
INNER JOIN
        children c
ON      c.pid = p.id
WHERE   p.x = 2

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

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

MySQL не очень хорош для распараллеливания и конвейеризации потоков результатов.

Понравился запрос:

SELECT  *
FROM    mytable
LIMIT 1

является мгновенным, в то время как этот (который семантически идентичен):

SELECT  *
FROM    (
        SELECT  *
        FROM    mytable
        )
LIMIT 1

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

Для Oracle, SQL Server и PostgreSQL приведенные выше запросы (и оба ваших запроса), скорее всего, приведут к тем же планам выполнения.

4 голосов
/ 14 июля 2009

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

2 голосов
/ 14 июля 2009

Зависит от того, насколько хороша база данных при оптимизации запроса.

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

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

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

0 голосов
/ 14 июля 2009

Для меня во втором запросе, который вы говорите, я не доверяю оптимизатору оптимизировать этот запрос, поэтому приведу несколько «подсказок».

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

0 голосов
/ 14 июля 2009

Вот почему у вас есть администраторы. Это полностью зависит от СУБД и от того, как настроены ваши таблицы и индексы, и какая из них работает быстрее всего.

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

  • о какой СУБД вы спрашиваете.
  • какие у вас индексы в таблицах.
  • множество других возможных элементов конфигурации (которые также могут зависеть от СУБД, например, от кластеризации).

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

0 голосов
/ 14 июля 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...