Почему этот запрос замедляется при использовании подзапроса

avatar
Charlie Collard
8 августа 2021 в 18:16
39
2
0

У меня есть база данных SQLite с 2 таблицами, одна из которых ссылается на другую:

> create table commenters (
    id integer primary key autoincrement,
    <snip>
    displayName text not null,
    <snip>
);
> create table comments (
    id integer primary key autoincrement,
    <snip>
    commenterID text not null,
    <snip>
);

В таблице комментариев есть индекс для commenterID:

> create index comments_commenter_id on comments (commenterID);

Следующие 2 запроса выполняются практически мгновенно при отдельном запуске:

> select id from commenters where displayName = "somename";
12345
> select * from comments where commenterID = 12345;
many results...

Для меня следующий запрос, который объединяет вышеперечисленное в подзапрос, должен быть точно таким же быстрым:

select * from comments where commenterID = (select id from commenters where displayName = "somename");

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

select comments.* 
from commenters left join comments 
on commenters.id = comments.commenterID
where commenters.displayName = "somename";

Мне кажется, что база данных не использует индекс для последних запросов, потому что результаты медленно просачиваются. Это известная особенность SQLite?

Источник
Stu
8 августа 2021 в 18:48
5

commenterID text. Это должно быть integer, чтобы соответствовать идентификатору, на который он ссылается.

Charlie Collard
8 августа 2021 в 19:12
0

О боже, я идиот. Благодарю вас!

Ответы (2)

avatar
Charlie Collard
9 августа 2021 в 10:04
0

Решение, указанное Стю, состояло в том, чтобы изменить commenterID во второй таблице на тип int.

avatar
Gordon Linoff
8 августа 2021 в 18:19
0

Вам нужен индекс для displayName :

create index idx_commenters_displayName on commenters(displayName);

И индекс на commenterid:

create index idx_comments_commenterid on comments(commenterid)

С =s все в порядке, но в более разговорной речи используется join:

select c.*
from comments c join
     commenters cr
     on cr.id = c.commenterID
where cr.displayName = 'somename';
Charlie Collard
8 августа 2021 в 18:24
0

Хм, кажется, это не ускоряет его. Таблица commenters намного меньше, чем comments. Кроме того, если бы проблема заключалась в displayName, этот запрос, несомненно, также выполнялся бы медленно, но это не так: select id from commenters where displayName = "somename";