簡體   English   中英

SQL:如何使用索引加速查詢

[英]SQL: How to speed up a query using indexing

我正在嘗試加快查詢的速度,以找到購買了1970年之前制造的摩托車並購買了2010年之后制造的另一輛摩托車的所有客戶。由於我的查詢運行非常緩慢,因此我認為在尋找更好的索引方面需要幫助。 我的嘗試記錄在下面:

CREATE TABLE CUSTOMER (
  id int PRIMARY KEY, 
  fname varchar(30),     
  lname varchar(30)
);

CREATE TABLE MOTORCYCLE (
  id int PRIMARY KEY, 
  name varchar(30), 
  year int -- Manufactured year
);

CREATE TABLE SALES (
  cid int,
  mid int,
  FOREIGN KEY(cid) REFERENCES CUSTOMER(id), 
  FOREIGN KEY(mid) REFERENCES MOTOCYCLE(id),
  PRIMARY KEY(pid, mid, role)
);

索引

這是我的索引(我對此有些猜測,但這是我的嘗試):

CREATE UNIQUE INDEX customerID on CUSTOMER(id);
CREATE INDEX customerName on CUSTOMER(fname, lname);

CREATE UNIQUE INDEX motorcycleID on MOTORCYCLE(id);
CREATE INDEX motorcycleName on MOTORCYCLE(name);
CREATE INDEX motorcycleYear on MOTORCYCLE(year);

CREATE INDEX salesCustomerMotorcycleID on SALES(cid, mid);       
CREATE INDEX salesCustomerID on SALES(cid);
CREATE INDEX castsMotorcycleID on SALES(mid);

查詢

我的查詢可以找到購買1970年之前和2010年之后生產的自行車的客戶:

SELECT fname, lname
FROM (SALES INNER JOIN CUSTOMER ON SALES.cid=CUSTOMER.id) INNER JOIN MOTORCYCLE ON MOTORCYCLE.id=SALES.mid
GROUP BY CUSTOMER.id
HAVING MIN(MOTORCYCLE.year) < 1970 AND MAX(MOTORCYCLE.year) > 2010;

這是另一個可以避免使用GROUP BYHAVING子句的查詢:

SELECT DISTINCT C.id, fname, lname
FROM (CUSTOMER as C inner join (SALES as S1 INNER JOIN MOTORCYCLE as M1 ON M1.id=S1.mid) on C.id=S1.cid) inner join (SALES as S2 inner join MOTORCYCLE as M2 on S2.mid=M2.id) on C.id=S2.cid
WHERE (M1.year < 1970 AND M2.year > 2010);

關於可以用來加快查詢速度的各種索引有什么建議嗎? 還是應該更改查詢?

UPDATE

我發現另一個查詢也可以,但是它也太慢了。 它已在上面添加。 不過,在查找索引以加快索引速度時可能會有所幫助。

當您使用EXPLAIN QUERY PLAN簽出查詢時,您會看到在兩種情況下,數據庫都會在過濾掉不需要的記錄(不需要的年份)之前查找許多相關記錄。

以下查詢在匹配之前查找摩托車ID; 哪一個速度更快取決於您的數據詳細信息,並且必須由您衡量:

SELECT *
FROM Customer
WHERE EXISTS (SELECT 1
              FROM Sales
              WHERE cid = Customer.id
                AND mid IN (SELECT id
                            FROM Motorcycle
                            WHERE year < 1970))
  AND EXISTS (SELECT 1
              FROM Sales
              WHERE cid = Customer.id
                AND mid IN (SELECT id
                            FROM Motorcycle
                            WHERE year > 2010));

SELECT *
FROM Customer
WHERE EXISTS (SELECT 1
              FROM Sales AS s1
              JOIN Sales AS s2 ON s1.cid = s2.cid
              WHERE s1.cid = Customer.id
                AND s1.mid IN (SELECT id
                               FROM Motorcycle
                               WHERE year < 1970)
                AND s2.mid IN (SELECT id
                               FROM Motorcycle
                               WHERE year > 2010));

SQL小提琴

在查詢中不使用聚合功能時為什么要使用分組方式? 如果您不希望看到任何重復,請使用distinct

暫無
暫無

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

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