SQLite 查询太慢

问题描述 投票:0回答:1

我有以下查询,速度非常慢。有没有其他方法可以提高搜索速度?

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
);
sqlite
1个回答
0
投票

您可能可以通过利用索引来稍微提高性能,但您似乎没有使用索引。

您还可以通过参考以下内容更好地理解哪些索引:-

举个例子,fullconcordance 表和 versesplain 表中的 bookid 列在 WHERE 子句和 JOIN 子句中都被引用,那么在两者上都有索引可以很好地提高效率。

理论上,这可以通过利用

EXPLAIN

来证明
  • EXPLAIN
    随后是 SELECT SQL,或者可能首先是
  • EXPLAIN QUERY PLAN
    (而不仅仅是解释)

也许可以考虑以下演示,它在添加一些索引之前和之后都会执行。

  • 请注意,虽然索引可以很好地提高 SELECT 的效率,但由于必须维护索引,因此会产生一些开销。

演示使用以下内容:-

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 子句。

  • 请注意,bookid 已被假定为 books 表的主键(因此考虑了该索引)。 ***这个答案并不是要真正解决问题,而是表明可能解决问题的路线。
  • 实际上确定好处需要向表中加载数据,并且可能会加载大量数据。
© www.soinside.com 2019 - 2024. All rights reserved.