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

#sql #performance #sqlite

Вопрос:

У меня есть база данных 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>
);
 

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

 > 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?

Комментарии:

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

2. О боже, я идиотка. Спасибо!

Ответ №1:

Вам нужен указатель на 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';
 

Комментарии:

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

Ответ №2:

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