Вложенные запросы SELECT иногда останавливаются - PullRequest
1 голос
/ 19 октября 2010

Я использовал sqlite3 в приложении на Python, и при тестировании мои запросы иногда приводят к зависанию программы.Грубый (из памяти) пример:

SELECT id,name FROM main_table WHERE name IN 
(SELECT name FROM another_table WHERE another_table.attribute IN 
('foo', 'bar', 'baz'))

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

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

Ответы [ 2 ]

1 голос
/ 19 октября 2010

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

Вот эквивалент с использованием JOIN:

SELECT DISTINCT
       x.id,
       x.name 
  FROM main_table x
  JOIN ANOTHER_TABLE y ON y.name = x.name
                      AND y.attribute IN ('foo', 'bar', 'baz')

Но учтите, что если в ANOTHER_TABLE имеется более одной записи, которая связана с записью MAIN_TABLE - JOIN будет создавать дубликаты. Отсюда необходимость в DISTINCT (или GROUP BY, если это ваше предпочтение).

EXISTS, вероятно, будет лучшим выбором, чем IN:

SELECT x.id,
       x.name 
  FROM main_table x
 WHERE EXISTS(SELECT NULL
                FROM ANOTHER_TABLE y 
               WHERE y.name = x.name
                 AND y.attribute IN ('foo', 'bar', 'baz'))
0 голосов
/ 19 октября 2010

выберите ... где ... в ... запросы часто работают плохо. Они обычно рассматриваются оптимизаторами как потенциально очень большая серия (name = val1 или name = val2 или ... или name = valn)

Попробуйте использовать внутренние соединения для подзапроса:

SELECT 
    id
    ,name 
FROM 
    main_table 
    INNER JOIN another_table on 
        main_table.name=another_table.name
        and another_table.attribute in (
            'foo','bar','baz'
        )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...