संक्षेप में उस विशेष क्वेरी पर ध्यान केंद्रित किया गया, और नमूना डेटा नीचे लोड किया गया। यह कुछ अन्य प्रश्नों को संबोधित करता है जैसे कि count(distinct ...)
दूसरों द्वारा उल्लिखित।
alias in the HAVING
या तो थोड़ा बेहतर प्रदर्शन करता है या इसके वैकल्पिक (क्वेरी के आधार पर) थोड़ा अधिक प्रदर्शन करता है।
यह एक पूर्व-मौजूदा तालिका का उपयोग करता है जिसमें लगभग 5 मिलियन पंक्तियां होती हैं जो इस answer के माध्यम से जल्दी से बनाई जाती है जिसमें 3 से 5 मिनट लगते हैं।
परिणामस्वरूप संरचना:
CREATE TABLE `ratings` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`thing` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5046214 DEFAULT CHARSET=utf8;
लेकिन बजाय InnoDB का उपयोग कर। रेंज आरक्षण आवेषण के कारण अपेक्षित आईएनएनओडीबी अंतर विसंगति उत्पन्न करता है। बस कह रहा है, लेकिन कोई फर्क नहीं पड़ता। 4.7 मिलियन पंक्तियां
टिम की अनुमानित स्कीमा के पास जाने के लिए तालिका को संशोधित करें।
rename table ratings to students; -- not exactly instanteous (a COPY)
alter table students add column camId int; -- get it near Tim's schema
-- don't add the `camId` index yet
निम्नलिखित में कुछ समय लगेगा। इसे बार-बार भाग में चलाएं या फिर आपका कनेक्शन टाइमआउट हो सकता है। अपडेट स्टेटमेंट में LIMIT क्लॉज के बिना टाइमआउट 5 मिलियन पंक्तियों के कारण है। नोट, हम में एक LIMIT क्लॉज है।
तो हम इसे आधे मिलियन पंक्ति पुनरावृत्तियों में कर रहे हैं। 1 और 20
update students set camId=floor(rand()*20+1) where camId is null limit 500000; -- well that took a while (no surprise)
जो यादृच्छिक संख्या के लिए एक स्तंभ सेट से ऊपर चल रहा है जब तक कोई camId
रिक्त है रखें।
मैं (पूरी बात 7 से 10 मिनट लगते हैं)
select camId,count(*) from students
group by camId order by 1 ;
1 235641
2 236060
3 236249
4 235736
5 236333
6 235540
7 235870
8 236815
9 235950
10 235594
11 236504
12 236483
13 235656
14 236264
15 236050
16 236176
17 236097
18 235239
19 235556
20 234779
select count(*) from students;
-- 4.7 Million rows
(निश्चित रूप से आवेषण के बाद) एक उपयोगी सूचकांक बनाएं 10 बार की तरह यह भाग गया।
create index `ix_stu_cam` on students(camId); -- takes 45 seconds
ANALYZE TABLE students; -- update the stats: http://dev.mysql.com/doc/refman/5.7/en/analyze-table.html
-- the above is fine, takes 1 second
परिसर तालिका बनाएं।
create table campus
( camID int auto_increment primary key,
camName varchar(100) not null
);
insert campus(camName) values
('one'),('2'),('3'),('4'),('5'),
('6'),('7'),('8'),('9'),('ten'),
('etc'),('etc'),('etc'),('etc'),('etc'),
('etc'),('etc'),('etc'),('etc'),('twenty');
-- ok 20 of them
भागो दो प्रश्नों:
SELECT students.camID, campus.camName, COUNT(students.id) as studentCount
FROM students
JOIN campus
ON campus.camID = students.camID
GROUP BY students.camID, campus.camName
HAVING COUNT(students.id) > 3
ORDER BY studentCount;
-- run it many many times, back to back, 5.50 seconds, 20 rows of output
और
SELECT students.camID, campus.camName, COUNT(students.id) as studentCount
FROM students
JOIN campus
ON campus.camID = students.camID
GROUP BY students.camID, campus.camName
HAVING studentCount > 3
ORDER BY studentCount;
-- run it many many times, back to back, 5.50 seconds, 20 rows of output
तो बार समान हैं। हर एक दर्जन बार दौड़ें।
EXPLAIN
उत्पादन दोनों
+----+-------------+----------+------+---------------+------------+---------+----------------------+--------+---------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+------+---------------+------------+---------+----------------------+--------+---------------------------------+
| 1 | SIMPLE | campus | ALL | PRIMARY | NULL | NULL | NULL | 20 | Using temporary; Using filesort |
| 1 | SIMPLE | students | ref | ix_stu_cam | ix_stu_cam | 5 | bigtest.campus.camID | 123766 | Using index |
+----+-------------+----------+------+---------------+------------+---------+----------------------+--------+---------------------------------+
औसत() फ़ंक्शन का उपयोग करने से, मैं एक 12% प्रदर्शन में उर्फ साथ having
में (समान EXPLAIN
उत्पादन के साथ) वृद्धि के बारे में हो रही है के लिए एक ही है दो प्रश्नों का पालन करें।
SELECT students.camID, campus.camName, avg(students.id) as studentAvg
FROM students
JOIN campus
ON campus.camID = students.camID
GROUP BY students.camID, campus.camName
HAVING avg(students.id) > 2200000
ORDER BY students.camID;
-- avg time 7.5
explain
SELECT students.camID, campus.camName, avg(students.id) as studentAvg
FROM students
JOIN campus
ON campus.camID = students.camID
GROUP BY students.camID, campus.camName
HAVING studentAvg > 2200000
ORDER BY students.camID;
-- avg time 6.5
और अंत में, DISTINCT
:
SELECT students.camID, count(distinct students.id) as studentDistinct
FROM students
JOIN campus
ON campus.camID = students.camID
GROUP BY students.camID
HAVING count(distinct students.id) > 1000000
ORDER BY students.camID; -- 10.6 10.84 12.1 11.49 10.1 9.97 10.27 11.53 9.84 9.98
-- 9.9
SELECT students.camID, count(distinct students.id) as studentDistinct
FROM students
JOIN campus
ON campus.camID = students.camID
GROUP BY students.camID
HAVING studentDistinct > 1000000
ORDER BY students.camID; -- 6.81 6.55 6.75 6.31 7.11 6.36 6.55
-- 6.45
उर्फ होने में लगातार 35% ही EXPLAIN
उत्पादन के साथ तेजी से चलाता है। नीचे देखा गया। तो वही स्पष्टीकरण आउटपुट दो बार दिखाया गया है न कि एक ही प्रदर्शन में, बल्कि एक सामान्य सुराग के रूप में।
+----+-------------+----------+-------+---------------+------------+---------+----------------------+--------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+----------+-------+---------------+------------+---------+----------------------+--------+----------------------------------------------+
| 1 | SIMPLE | campus | index | PRIMARY | PRIMARY | 4 | NULL | 20 | Using index; Using temporary; Using filesort |
| 1 | SIMPLE | students | ref | ix_stu_cam | ix_stu_cam | 5 | bigtest.campus.camID | 123766 | Using index |
+----+-------------+----------+-------+---------------+------------+---------+----------------------+--------+----------------------------------------------+
अनुकूलक मैं अपने आप को के बाहर हर समय एक मूर्ख बनाने के लिए विशेष रूप से DISTINCT.
के लिए, इस समय होने में उर्फ के पक्ष में दिखाई देता है। – Drew
संभावित डुप्लिकेट [खंड में एक एसक्यूएल पैरामीटरेट करें] (http://stackoverflow.com/questions/337704/parameterize-an-sql-in-clause) –