mysql

2012-09-21 5 views
8

से कई वर्गीकृत किया मूल्यों को प्राप्त मैं इस तरह एक मेज संरचना है:mysql

CREATE TABLE `test` (
    `a` tinyint(3) unsigned DEFAULT 0, 
    `b` tinyint(3) unsigned DEFAULT 0, 
    `c` tinyint(3) unsigned DEFAULT 0, 
    `d` tinyint(3) unsigned DEFAULT 0, 
    `e` tinyint(3) unsigned DEFAULT 0 
); 

यह कुछ स्तंभ 0-200 से मूल्यों है कि साथ के बारे में 30 स्तंभ हैं (ए, बी) और कुछ केवल 5 मान (0,1,2,3,4) (कॉलम सीडी)। Aprox हैं। तालिका में 120k पंक्तियां।

प्रति पंक्ति आइटम्स की संख्या को दिखाने के लिए मैं प्रत्येक स्तंभ के लिए एक प्रश्न का उपयोग करें:

select a, count(*) FROM test group by a; 
select b, count(*) FROM test group by b; 
select c, count(*) FROM test group by c; 
select d, count(*) FROM test group by d; 
select e, count(*) FROM test group by e; 

इस के साथ समस्या यह है कि यह 30 प्रश्नों (प्रति स्तंभ एक) और मूल रूप से सक्रिय कर देगा है एक ही सेट के ऊपर जाता है प्रत्येक बार डेटा का।

क्या ऐसा करने का कोई बेहतर तरीका है?

मैंने ग्रुप बाय के साथ रोलअप के साथ प्रयास किया है, लेकिन इसके परिणामस्वरूप एक बड़े परिणामस्वरूप जो प्रत्येक व्यक्तिगत क्वेरी की तुलना में प्रक्रिया में धीमा है।

आप SQLfiddle पर डेटा की एक चयन देख सकते हैं: http://sqlfiddle.com/#!2/a9fd8/1

+0

हर बार 'अस्थायी उपयोग करना; Filesort' का उपयोग करके आप अपने कॉलम पर सॉर्ट किए गए इंडेक्स जोड़ सकते हैं? – edze

+0

किस पर मुझे एक इंडेक्स जोड़ना चाहिए? सब पर? यह भी ध्यान रखें, कि कुछ अन्य फ़ील्ड हैं जिन पर खोज की गई है (मेरे पास उन पर एक सूचकांक है)। – Nin

+2

हां, समूह के लिए आवश्यक प्रत्येक कॉलम के लिए एक आदेश दिया गया इंडेक्स। यदि आप 'a' से समूह करते हैं, तो MySQL आपकी तालिका को 'ए'' से सॉर्ट करना शुरू कर देता है। मुझे लगता है कि यह तुम्हारी बाधा है। – edze

उत्तर

2

शायद ऐसा कुछ तेजी से काम करेगा।

select qq, q, count(*) from 
(
select 'a' qq, a q FROM test 
union all select 'b' qq, b q FROM test 
union all select 'c' qq, c q FROM test 
union all select 'd' qq, d q FROM test 
union all select 'e' qq, e q FROM test 
) t 
group by qq, q; 
+0

प्रदर्शन वही – Nin

3
select 'a' as `column`, a as data, count(*) 
FROM test 
group by 'a', a 
union 
select 'b', b, count(*) 
FROM test 
group by 'b', b 
union 
select 'c', c, count(*) 
FROM test 
group by 'c', c 
union 
select 'd', d, count(*) 
FROM test 
group by 'd', d 
union 
select 'e', e, count(*) 
FROM test 
group by 'e', e 

अगर यह किसी भी बेहतर है, लेकिन कम से कम योजनाकार यह अनुकूलन करने के लिए एक मौका होगा है पता नहीं है।

+0

यह लगभग मूल (वास्तव में थोड़ा धीमा) जैसा ही करता है। – Nin

1

संपादित: इस जवाब पूरी तरह से ट्रैक से दूर है

निम्नलिखित का प्रयास करें; यह एक क्लीनर क्वेरी है, बस एक पास के साथ है, लेकिन मैं DISTINCT की वजह से यकीन है कि यह कितना अच्छा प्रदर्शन नहीं कर रहा हूँ:

SELECT 
    COUNT(DISTINCT a) AS a, 
    COUNT(DISTINCT b) AS b, 
    COUNT(DISTINCT c) AS c, 
    COUNT(DISTINCT d) AS d, 
FROM 
    t 
; 
+0

है, लेकिन यह मुझे केवल अलग-अलग आइटमों की संख्या देगा, न कि उनके आइटम के साथ उन वस्तुओं का मूल्य। – Nin

+0

हूप्स। मेरी गलती; पूरी तरह से ट्रैक –

0

कुछ भी नहीं मूल है, लेकिन आप इस एक कोशिश कर सकते।

SELECT t.col, t.val, t.c FROM 
(
    SELECT 'a' col, a val, count(*) c FROM test GROUP BY a 
    UNION ALL 
    SELECT 'b' col, b val, count(*) c FROM test GROUP BY b 
    UNION ALL 
    SELECT 'c' col, c val, count(*) c FROM test GROUP BY c 
    UNION ALL 
    SELECT 'd' col, d val, count(*) c FROM test GROUP BY d 
    UNION ALL 
    SELECT 'e' col, e val, count(*) c FROM test GROUP BY e 
) t 

लेकिन यदि प्रदर्शन यहां मुद्दा है तो मैं वही सुझाव सुझाता हूं जो @edze सुझाया गया है - कॉलम पर सूचकांक (हाँ सभी 30)। यह अंतरिक्ष खर्च करेगा, लेकिन प्रदर्शन में वृद्धि होगी। या यहाँ तक कि इस कार्य के लिए दृश्य तालिका

CREATE TABLE `test_view` (
    `col` char(1), 
    `value` tinyint(3), 
    `count` int 
); 

बनाने और उसके बाद सिर्फ सरल चयन करते हैं यह अक्सर किया जाता है।

0

पारिस्थितिक विज्ञान के आधार पर यह एक बार कुल डेटा की एक तालिका बनाने के लिए और अधिक कुशल हो सकता है और फिर जब भी यह तालिका संशोधित होती है तो इसे अद्यतित रखें। आपकी कुल डेटा तालिका में प्रत्येक (वर्तमान) मान के लिए एक पंक्ति होगी, और फिर 30 अतिरिक्त कॉलम गिना जाएगा। फिर आप मूल पर ट्रिगर्स डाल सकते हैं जो गणनाओं को अपडेट करते हैं। स्वाभाविक रूप से जो मूल तालिका पर लिखने के संचालन को धीमा कर देगा, हालांकि 30 इंडेक्स जोड़ना होगा।

+0

कॉलम पर केवल 5 विशिष्ट मानों के साथ एक इंडेक्स जोड़ना मदद नहीं करता है क्योंकि MySQL शायद उस अनुक्रमणिका को अनदेखा कर देगा। एक समग्र तालिका अच्छी लगती है लेकिन इस मामले में मैं पहले से ही कुछ कॉलम के आधार पर इस तालिका का सबसेट चुनता हूं, इसलिए इस मामले में एक समग्र तालिका नहीं की जा सकती है। – Nin

 संबंधित मुद्दे