#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 .