我有以下查询,速度非常慢。有没有其他方法可以提高搜索速度?
SELECT * FROM
(SELECT DISTINCT
c.id AS VERSEid01,
c.BookID,
c.Word
FROM FullConcordance c
WHERE c.BookID = \(bookID) AND c.Word = '\(myString)'
),
(SELECT DISTINCT
b.Book,
v.id AS VERSEid02,
v.BookID,
v.Chapter,
v.Verse,
v.VerseText
FROM VersesPlain v
JOIN Books b ON v.BookID = b.id
WHERE v.BookID = \(bookID)
)
表格是:
CREATE TABLE IF NOT EXISTS "FullConcordance" (
"Word" text,
"BookID" integer,
"id" integer
);
CREATE TABLE IF NOT EXISTS "VersesPlain" (
"id" integer PRIMARY KEY,
"BookID" integer,
"Chapter" integer,
"Verse" integer,
"VerseText" text
);
您可能可以通过利用索引来稍微提高性能,但您似乎没有使用索引。
您还可以通过参考以下内容更好地理解哪些索引:-
举个例子,fullconcordance 表和 versesplain 表中的 bookid 列在 WHERE 子句和 JOIN 子句中都被引用,那么在两者上都有索引可以很好地提高效率。
理论上,这可以通过利用
EXPLAIN
来证明
EXPLAIN
随后是 SELECT SQL,或者可能首先是EXPLAIN QUERY PLAN
(而不仅仅是解释)也许可以考虑以下演示,它在添加一些索引之前和之后都会执行。
演示使用以下内容:-
DROP TABLE IF EXISTS fullconcordance;
DROP TABLE IF EXISTS versesplain;
DROP TABLE IF EXISTS books;
/* Create the tables according to the information available from the question */
CREATE TABLE IF NOT EXISTS FullConcordance (
Word text,
BookID integer,
id integer
);
CREATE TABLE IF NOT EXISTS VersesPlain (
id integer PRIMARY KEY,
BookID integer,
Chapter integer,
Verse integer,
VerseText text
);
CREATE TABLE IF NOT EXISTS books (
id integer PRIMARY KEY,
book text
);
/* Do the EXPLAIN QUERY PLAN WITHOUT ADDITIONAL INDEXES */
EXPLAIN QUERY PLAN
SELECT * FROM
(SELECT DISTINCT
c.id AS VERSEid01,
c.BookID,
c.Word
FROM FullConcordance c
WHERE c.BookID = bookID AND c.Word = '\(myString)'
),
(SELECT DISTINCT
b.Book,
v.id AS VERSEid02,
v.BookID,
v.Chapter,
v.Verse,
v.VerseText
FROM VersesPlain v
JOIN Books b ON v.BookID = b.id
WHERE v.BookID = bookID
);
EXPLAIN
SELECT * FROM
(SELECT DISTINCT
c.id AS VERSEid01,
c.BookID,
c.Word
FROM FullConcordance c
WHERE c.BookID = bookID AND c.Word = '\(myString)'
),
(SELECT DISTINCT
b.Book,
v.id AS VERSEid02,
v.BookID,
v.Chapter,
v.Verse,
v.VerseText
FROM VersesPlain v
JOIN Books b ON v.BookID = b.id
WHERE v.BookID = bookID
);
/* ADD some indexes that may be useful*/
DROP INDEX IF EXISTS idx_versesplain_bookid;
CREATE INDEX IF NOT EXISTS idx_versesplain_bookid ON versesplain (bookid);
DROP INDEX IF EXISTS idx_fullconcordance_bookid;
CREATE INDEX IF NOT EXISTS idx_fullconcordance_bookid ON fullconcordance (bookid);
DROP INDEX IF EXISTS idx_fullconcordance_word;
CREATE INDEX IF NOT EXISTS idx_fullconcordance_word ON fullconcordance (word);
/* Now do the EXPLAIN QUERY PLAN WITH THE INDEXES */
EXPLAIN QUERY PLAN
SELECT * FROM
(SELECT DISTINCT
c.id AS VERSEid01,
c.BookID,
c.Word
FROM FullConcordance c
WHERE c.BookID = bookID AND c.Word = '\(myString)'
),
(SELECT DISTINCT
b.Book,
v.id AS VERSEid02,
v.BookID,
v.Chapter,
v.Verse,
v.VerseText
FROM VersesPlain v
JOIN Books b ON v.BookID = b.id
WHERE v.BookID = bookID
);
EXPLAIN
SELECT * FROM
(SELECT DISTINCT
c.id AS VERSEid01,
c.BookID,
c.Word
FROM FullConcordance c
WHERE c.BookID = bookID AND c.Word = '\(myString)'
),
(SELECT DISTINCT
b.Book,
v.id AS VERSEid02,
v.BookID,
v.Chapter,
v.Verse,
v.VerseText
FROM VersesPlain v
JOIN Books b ON v.BookID = b.id
WHERE v.BookID = bookID
);
/* Clean Up The Demo Environment */
DROP TABLE IF EXISTS fullconcordance;
DROP TABLE IF EXISTS versesplain;
DROP TABLE IF EXISTS books;
它产生 4 个输出,一个
EXAPLIN QUERY PLAN
和一个 EXPLAIN
用于索引之前和之后。
EXPLAIN
更深入,因此以下仅针对EXPLAIN QUERY PLAN
的
索引之前(结果 1):-
之后(结果 3):-
突出显示的细节表明索引已经发挥作用,而不是全表扫描。第一个显示,不是搜索 fullconcordance 表中的每一行,而是使用 word 列上的索引来定位单词,同样适用于 versesplain 表上 bookid 的 WHERE 子句。