我是MySQL的性能優化新手&需要您的幫助,以獲得有關在我們的設計中稍後替換表的視圖。MySQL中的有序視圖的性能問題
表要被替換被稱爲用戶和具有下列屬性: 該users2視圖具有下列屬性:
當我執行正常上兩個對象選擇,它們在同一時間作出迴應:
SELECT *
FROM `users`
SELECT *
FROM `users2`
但這些查詢的有序版本導致不同PERFORMA NCE:該表是一個慢一點(需要不到兩秒鐘),認爲需要十倍左右這個時間:
SELECT *
FROM `users`
ORDER BY `lastName`, `firstName`
SELECT *
FROM `users2`
ORDER BY `lastName`, `firstName`
顯然,一個上表 '一個' 上Countries_ID屬性(地址)ALL是製造特魯因此我做了如下:
ALTER TABLE addresses ADD INDEX (Countries_ID);
這個指數沒有改變任何東西。所以,我問你的意見什麼可以做得更好。
注意1:是否有辦法在臨時列上創建索引Countries_ID_2? 注意2:users2視圖與下面的SQL查詢創建:
CREATE OR REPLACE VIEW users2 AS
(SELECT p.username
, p.password
, p.firstName
, p.lastName
, p.eMail AS email
, a.settlement AS city
, s.name AS country
, pl.languages
, p.description
, p.ID AS ID
, p.phone1
, p.phone2
, CONCAT_WS(' ', a.street, a.addition) AS address
, p.status
, p.publicMail
, ad.name AS Betreuer
FROM addresses a
INNER JOIN addresses_have_persons ap ON a.ID = ap.Addresses_ID
INNER JOIN countries c ON a.Countries_ID = c.ID
INNER JOIN persons p ON a.ID = p.addressID
AND ap.Persons_ID = p.ID
INNER JOIN states s ON a.States_ID = s.ID
INNER JOIN persons_language pl ON p.ID = pl.ID
LEFT JOIN advisors ad ON p.advisorID = ad.ID
-- LEFT JOIN titles t ON t.ID = ad.titleID
);
注意3:雖然很多在人表NULL領域,沒有一個單一的排在那裏這些字段完全是NULL。
編輯:
CREATE OR REPLACE VIEW persons_language AS
(SELECT lp.Persons_ID AS ID
, GROUP_CONCAT(DISTINCT l.name ORDER BY l.name SEPARATOR ', ') AS languages
FROM languages l
, languages_have_persons lp
WHERE l.ID = lp.Languages_ID
GROUP BY lp.Persons_ID);
沒有ORDER BY,語言的名稱不按字母順序排序,這是我目前想要的。也許,我們可以決定讓它們以任何順序,但我們會看到。
目前,我做了如下修改沒有任何性能改進:
ALTER TABLE addresses ADD INDEX (Countries_ID);
ALTER TABLE addresses ADD INDEX (States_ID);
ALTER TABLE addresses_have_persons ADD INDEX (Addresses_ID);
ALTER TABLE languages ADD INDEX (name);
ALTER TABLE persons ADD INDEX (addressID);
ALTER TABLE persons ADD INDEX (address2ID);
ALTER TABLE persons ADD INDEX (address3ID);
ALTER TABLE persons ADD INDEX (advisorID);
編輯2:
我也討論了在其他網站上這個問題。還有的討論讓我做了如下修改是更接近第三範式:
CREATE OR REPLACE TABLE accounts
(ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY
, username VARCHAR(50) NOT NULL UNIQUE
, password VARCHAR(255) NOT NULL
, eMail VARCHAR(100) NOT NULL
, Persons_ID INT NOT NULL
);
INSERT INTO accounts (username, password, eMail, Persons_ID)
SELECT username, password, eMail, ID
FROM persons;
新表persons_information承載所有附加信息:
我重建了users2用下面的命令:
CREATE OR REPLACE VIEW users2 AS
(SELECT ac.username
, ac.password
, p.firstName
, p.lastName
, ac.eMail AS email
, adr.settlement AS city
, s.name AS country
, pl.languages
, pi.description
, ac.Persons_ID AS ID
, pi.phone1
, pi.phone2
, CONCAT_WS(' ', adr.street, adr.addition) AS address
, p.status
, pi.publicMail
, adv.name AS Betreuer
FROM accounts ac
INNER JOIN persons p ON ac.Persons_ID = p.ID
INNER JOIN persons_information pi ON p.ID = pi.ID
INNER JOIN addresses adr ON adr.ID = pi.addressID
INNER JOIN addresses_have_persons ap ON adr.ID = ap.Addresses_ID
AND ap.Persons_ID = p.ID
INNER JOIN countries c ON adr.Countries_ID = c.ID
INNER JOIN states s ON adr.States_ID = s.ID
INNER JOIN persons_language pl ON p.ID = pl.ID
LEFT JOIN advisors adv ON pi.advisorID = adv.ID
-- LEFT JOIN titles t ON t.ID = adv.titleID
);
的SELECT _ FROM users2是快,但如果我添加一個ORDER BY姓氏,名字,需要約25秒獲得響應。
這裏是* EXPLAIN SELECT *從users2結果*命令:
我也(重新)創建下列指標:
ALTER TABLE addresses ADD INDEX (Countries_ID);
ALTER TABLE addresses ADD INDEX (States_ID);
ALTER TABLE addresses_have_persons ADD INDEX (Persons_ID);
ALTER TABLE languages ADD INDEX (name);
ALTER TABLE persons_information ADD INDEX (addressID);
ALTER TABLE persons_information ADD INDEX (address2ID);
ALTER TABLE persons_information ADD INDEX (address3ID);
ALTER TABLE persons_information ADD INDEX (advisorID);
我想一個原因問題是創建如下persons_language觀點:
CREATE OR REPLACE VIEW persons_language AS
(SELECT lp.Persons_ID AS ID
, GROUP_CONCAT(DISTINCT l.name ORDER BY l.name SEPARATOR ', ') AS languages
FROM languages l
INNER JOIN languages_have_persons lp ON l.ID = lp.Languages_ID
GROUP BY lp.Persons_ID);
編輯3: 對於那些有興趣,我想補充解釋的persons_language觀點:
編輯4: 今天的數據庫會後,我們決定刪除所有對象與地址信息相關&用
重新創建視圖CREATE OR REPLACE VIEW `users2` AS
(SELECT ac.username
, ac.password
, p.firstName
, p.lastName
, ac.eMail AS email
, pl.languages
, pi.description
, ac.Persons_ID AS ID
, pi.phone1
, pi.phone2
, p.status
, pi.publicMail
, adv.name AS Betreuer
FROM accounts ac
INNER JOIN persons p ON ac.Persons_ID = p.ID
INNER JOIN persons_information pi ON p.ID = pi.ID
INNER JOIN persons_language pl ON p.ID = pl.ID
INNER JOIN advisors adv ON pi.advisorID = adv.ID
WHERE ac.password IS NOT NULL
);
我還創建了一個索引與
CREATE INDEX LanguagesPersonsIndex ON `languages_have_persons` (`Languages_ID`, `Persons_ID`);
的EXPLAIN命令顯示新索引在使用和一個後的延遲選擇與ORDER BY子句與新的,更小的觀點是約18秒。下面是新的結果: 我的問題是:我可以做更多,以提高性能?
謝謝你的回覆@Renato Tarso!不幸的是,我在一個必要的視圖中有一個ORDER BY。看到上面的問題編輯。所有的訂單/分組/關係屬性都是關鍵。 – Sae1962
「...是主鍵」(當然,沒有意見顧問和persons_language主鍵) – Sae1962
@ Sae1962,檢查我的答案變化。我希望這是有用的。祝你好運。 –