[英]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 BY
和HAVING
子句的查詢:
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));
在查詢中不使用聚合功能時為什么要使用分組方式? 如果您不希望看到任何重復,請使用distinct
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.