Почему SQLite занимает такое долгое время для выборки данных?

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

Запросите каждый берет приблизительно 30 мс, но 150 мс для выборки данных из базы данных.

SELECT 
    id
FROM 
    featurevalues as featval3
WHERE 
    featval3.feature IN (?,?,?,?) 
AND
    EXISTS
    (
        SELECT
            1
        FROM
            product_to_value,
            product_to_value as prod2,
            features,
            featurevalues
        WHERE
            product_to_value.feature = features.int
        AND
            product_to_value.value = featurevalues.id
        AND
            features.id = ? 
        AND
            featurevalues.id IN (?,?)
        AND
            product_to_value.product = prod2.product
        AND
            prod2.value = featval3.id
    )

Запросите два, берет приблизительно 3 мс - это - то, которое я поэтому предпочитаю - но также и берет 170 мс для выборки данных.

SELECT 
    (
        SELECT
            prod2.value
        FROM
            product_to_value,
            product_to_value as prod2,
            features,
            featurevalues
        WHERE
            product_to_value.feature = features.int
        AND
            product_to_value.value = featurevalues.id
        AND
            features.id = ? 
        AND
            featurevalues.id IN (?,?)
        AND
            product_to_value.product = prod2.product
        AND
            prod2.value = featval3.id
    ) as id
FROM 
    featurevalues as featval3
WHERE 
    featval3.feature IN (?,?,?,?) 

170 мс, кажется, связаны с количеством строк от таблицы featval3. После того, как индекс используется на featval3.feature В (????), 151 объект "остается" в featval3.

Действительно ли там что-то очевидно, что я отсутствую относительно медленной выборки? Насколько я знаю, что все правильно индексируется.. Я смущен, потому что второй запрос только берет сверкающие 3 мс для выполнения.

Обновление

Это - то, что я получаю, когда я выполняю ОБЪЯСНЕНИЕ на втором запросе:

0 Trace 0 0 0 00 
1 Variable 4 1 4 00 
2 Goto 0 88 0 00 
3 OpenRead 5 6883 0 00 
4 If 6 16 0 00 
5 Integer 1 6 0 00 
6 OpenEphemeral 7 1 0 00 
7 Null 0 8 0 00 
8 MakeRecord 1 1 8 00 
9 IdxInsert 7 8 0 00 
10 MakeRecord 2 1 8 00 
11 IdxInsert 7 8 0 00 
12 MakeRecord 3 1 8 00 
13 IdxInsert 7 8 0 00 
14 MakeRecord 4 1 8 00 
15 IdxInsert 7 8 0 00 
16 Rewind 7 86 0 00 
17 Column 7 0 5 00 
18 IsNull 5 85 0 00 
19 Affinity 5 1 0 00 
20 SeekGe 5 85 5 00 
21 IdxGE 5 85 5 01 
22 Null 0 10 0 00 
23 Integer 1 11 0 00 
24 MustBeInt 11 0 0 00 
25 IfZero 11 82 0 00 
26 Variable 1 12 3 00 
27 OpenRead 2 25 0 00 
28 OpenRead 8 7005 0 00 
29 OpenRead 9 26 0 00 
30 OpenRead 10 6732 0 00 
31 OpenRead 11 6766 0 00 
32 Column 5 1 15 00 
33 IsNull 15 77 0 00 
34 Affinity 15 1 0 00 
35 SeekGe 8 77 15 00 
36 IdxGE 8 77 15 01 
37 IdxRowid 8 8 0 00 
38 Seek 2 8 0 00 
39 Column 2 0 16 00 
40 IsNull 16 76 0 00 
41 Affinity 16 1 0 00 
42 SeekGe 9 76 16 00 
43 IdxGE 9 76 16 01 
44 Column 9 1 17 00 
45 IsNull 17 75 0 00 
46 SCopy 12 18 0 00 
47 IsNull 18 75 0 00 
48 Affinity 17 2 0 00 
49 SeekGe 10 75 17 00 
50 IdxGE 10 75 17 01 
51 If 20 59 0 00 
52 Integer 1 20 0 00 
53 OpenEphemeral 13 1 0 00 
54 Null 0 21 0 00 
55 MakeRecord 13 1 21 00 
56 IdxInsert 13 21 0 00 
57 MakeRecord 14 1 21 00 
58 IdxInsert 13 21 0 00 
59 Rewind 13 74 0 00 
60 Column 13 0 19 00 
61 IsNull 19 73 0 00 
62 Affinity 19 1 0 00 
63 SeekGe 11 73 19 00 
64 IdxGE 11 73 19 01 
65 Column 9 2 21 00 
66 Column 11 0 7 00 
67 Ne 7 72 21 6a 
68 Column 8 0 22 00 
69 Move 22 10 1 00 
70 AddImm 11 -1 0 00 
71 IfZero 11 77 0 00 
72 Next 11 64 0 00 
73 Next 13 60 0 00 
74 Next 10 50 0 00 
75 Next 9 43 0 00 
76 Next 8 36 0 00 
77 Close 2 0 0 00 
78 Close 8 0 0 00 
79 Close 9 0 0 00 
80 Close 10 0 0 00 
81 Close 11 0 0 00 
82 SCopy 10 9 0 00 
83 ResultRow 9 1 0 00 
84 Next 5 21 0 00 
85 Next 7 17 0 00 
86 Close 5 0 0 00 
87 Halt 0 0 0 00 
88 Transaction 0 0 0 00 
89 VerifyCookie 0 319 0 00 
90 TableLock 0 14 0 00 
91 TableLock 0 25 0 00 
92 TableLock 0 11 0 00 
93 Goto 0 3 0 00

Не уверенный, что это означает как бы то ни было.

7
задан Braiam 22 April 2014 в 15:43
поделиться

4 ответа

Вам, вероятно, следует использовать здесь СОЕДИНЕНИЯ, а использование коррелированных подзапросов вполне может замедлить работу . Хотя это правда, что часто оптимизатор может выполнить перекрестное соединение с предложением where, как если бы это было соединение, а также может выполнять коррелированные подзапросы как соединения, я бы не стал рассчитывать на то, что SQLite сможет сделать это во всех случаях. Переписывание вашего запроса с помощью JOIN, я думаю, дает следующее:

SELECT DISTINCT prod2.value AS id
FROM product_to_value
JOIN features ON product_to_value.feature = features.int
JOIN product_to_value as prod2 ON product_to_value.product = prod2.product
JOIN featurevalues as featval3 ON prod2.value = featval3.id
JOIN featurevalues ON product_to_value.value = featurevalues.id
WHERE features.id = ?
AND featurevalues.id IN (?,?)
AND featval3.feature IN (?,?,?,?)

Попробуйте это и убедитесь, что это быстрее (и все же дает правильный результат).

3
ответ дан 7 December 2019 в 05:19
поделиться

Используйте "Начать транзакцию" и "Завершить транзакцию" каждый раз, когда вы пишете запрос sql. Это объясняется здесь, а также много другой полезной информации:

Часто задаваемые вопросы по оптимизации SQLite

Вы можете проверить детали индексации в предложении where здесь:

Обзор оптимизатора запросов SQLite

-1
ответ дан 7 December 2019 в 05:19
поделиться

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

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

4
ответ дан 7 December 2019 в 05:19
поделиться

Почему бы не взглянуть на план запроса и не определить ответ самостоятельно? Вот ссылка: Как я могу проанализировать выполнение запроса Sqlite?

2
ответ дан 7 December 2019 в 05:19
поделиться
Другие вопросы по тегам:

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