簡體   English   中英

如何提高多對多SQL查詢的性能?

[英]How can I improve performance of a many-to-many SQL query?

我在書籍和流派之間有很多對很多的關系。 例如,“霍比特人”圖書可能具有類型“孩子”,“小說”和“幻想”。

這是模式:

CREATE TABLE "genre" (
    "id" integer NOT NULL PRIMARY KEY,
    "name" varchar(50) NOT NULL
)
;
CREATE TABLE "book_genres" (
    "book_id" integer NOT NULL REFERENCES "book" ("id"),
    "genre_id" integer NOT NULL REFERENCES "genre" ("id"),
    CONSTRAINT book_genres_pkey PRIMARY KEY (book_id, genre_id)
)
;
CREATE TABLE "book" (
    "id" integer NOT NULL PRIMARY KEY,
    "name" varchar(255) NOT NULL,
    "price" real NOT NULL
)
;

以及索引:

CREATE INDEX "book_genres_36c249d7" ON "book_genres" ("book_id");
CREATE INDEX "book_genres_33e6008b" ON "book_genres" ("genre_id");
CREATE INDEX "book_5a5255da" ON "book" ("price");

行數:

  • 體裁:30
  • book_genre:800,000
  • 預定:200,000

我正在嘗試用SQL編寫查詢,以查詢按價格排序的特定類型的所有書籍,而沒有重復。

這是我這樣做的查詢:

SELECT name, price 
FROM book 
WHERE book.id 
IN 
    (SELECT book_id 
    FROM book_genres
    WHERE genre_id = 1
    OR genre_id = 2)
ORDER BY price LIMIT 10

我的問題是性能。 該查詢最多可能需要2000毫秒才能執行。 如何提高性能?

我對數據庫(Postgres 9.3)具有完全控制權,因此可以添加視圖,索引或非規范化。 我也使用Django,因此可以使用Python / Django執行多個查詢以在內存中執行操作。

SELECT b.name, b.price
FROM book b
WHERE EXISTS (
    SELECT *
    FROM book_genres bg
    WHERE bg.book_id = b.id 
    AND bg.genre_id IN( 1 , 2)
    )
ORDER BY b.price 
LIMIT 10
        ;

price + LIMIT的訂單可能會導致性能下降:檢查查詢計划。

加上:用“反向”索引替換單列索引:將book_id設為FK進入books.id,並且(也許)省略代理鍵ID


CREATE TABLE book_genres
        ( book_id integer NOT NULL REFERENCES book (id)
        , genre_id integer NOT NULL REFERENCES genre (id)
        , PRIMARY KEY (book_id, genre_id)
        ) ;
CREATE INDEX ON book_genres  (genre_id,book_id);

在大多數情況下,您可以使用JOIN而不是子查詢來提高性能(盡管它取決於許多因素,所以):

SELECT * 
FROM 
(
   SELECT b.name, b.price 
   FROM book b JOIN book_genres g ON b.book.id = g.book_id 
                              AND g.genre_id = 1
   UNION

   SELECT b.name, b.price 
   FROM book b JOIN book_genres g ON b.book.id = g.book_id 
                              AND g.genre_id = 2
)
ORDER BY price LIMIT 10

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM