2011-11-07 14 views
11

पिछले पिछले दिनों में मैंने अपनी क्वेरी को अनुकूलित करने के लिए अजीब कुछ अजीब देखा। मैं एक साधारण क्वेरी जो की तरह कुछ करता है:MYSQL - नहीं बनाम var = false

SELECT id,name,amount FROM reservations WHERE NOT canceled ORDER BY name ASC 

मैंने देखा mysql किसी भी सूचकांक का उपयोग नहीं किया गया था, इसलिए मैं कुछ प्रयोग करना शुरू कर दिया। आकस्मिक रूप से मैंने "रद्द नहीं किया गया" के साथ "रद्द नहीं किया गया" बदल दिया, और फिर, माइस्क्ल ने इंडेक्स के रूप में "रद्द" का उपयोग करना शुरू कर दिया।

SELECT ... FROM reservations WHERE canceled ORDER BY ... 

एक ही परिणाम: उसके बाद मैं विपरीत उपयोग करने की कोशिश! जब मैं इसे "रद्द = सत्य" में बदलता हूं तो सूचकांक फिर से काम करता है।

मेरा सवाल है: कैसे आते हैं ?! "सुरुचिपूर्ण" तरीके से "नहीं" का उपयोग नहीं कर रहा है? किसी भी तरह से मैं इसके लिए कोई फर्क नहीं पड़ता।

मैं इंजन के रूप में InnoDB का उपयोग कर रहा हूं, लेकिन मुझे MyISAM का उपयोग करके एक ही परिणाम मिलता है। क्या कोई चीजों को स्पष्ट कर सकता है? धन्यवाद।

संपादित करें: तालिका संरचना

CREATE TABLE `reservations` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `trip_code` varchar(10) DEFAULT NULL, 
    `departure_date` date DEFAULT NULL, 
    `amount` float DEFAULT NULL, 
    `name` varchar(45) DEFAULT NULL, 
    `canceled` tinyint(1) NOT NULL DEFAULT '0', 
    `created_date` date NOT NULL, 
    `creator_user` int(11) NOT NULL DEFAULT '1', 
    `last_update_user` int(11) NOT NULL DEFAULT '1', 
    PRIMARY KEY (`id`), 
    KEY `trip_code` (`trip_code`), 
    KEY `departure_date` (`departure_date`), 
    KEY `created_date` (`created_date`), 
    KEY `canceled` (`canceled`) 
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=123181 ; 
+0

आप किस संस्करण का उपयोग करते हैं? – neworld

+0

सर्वर संस्करण: 5.1.43-समुदाय – Phoenix

+0

क्या आप तालिका के डीडीएल को पोस्ट कर सकते हैं। –

उत्तर

2

मैं MYSQL से परिचित नहीं हूँ, लेकिन तार्किक सोच, मैं इसे इस तरह समझ सकते हैं:
सूचकांक एक की तरह है फ़ोन बुक, जब आप "कोहेन" खोज रहे हैं, तो आप इसे तुरंत प्राप्त कर सकते हैं।
लेकिन यदि आप "कोहेन" की तलाश में हैं, तो आपको प्रत्येक प्रविष्टि पर दौड़ना होगा, और जांचें कि यह "कोहेन" से अलग है या नहीं।
तो जब आप विशिष्ट मान की तलाश में हैं, तो यह केवल इसके लिए दिखता है। और जब आप का उपयोग नहीं कर रहे हैं, तो यह tinyint(1) के अंदर फिट हो सकता है (जैसा कि मुझे लगता है कि यह केवल 1 या 0 नहीं है, है ना?)।

+0

मुझे लगता है कि वे इस सवाल में संकेत देते हैं कि 'जहां रद्द किया गया' सूचकांक का भी उपयोग नहीं करता है। हालांकि यह स्पष्ट नहीं है कि "वही परिणाम" क्या है। –

+0

ठीक है, मुझे लगता है कि 'रद्द किया गया' सत्य है जब 'रद्द किया गया मान 1, 2 या 3 है ... तो यह अभी भी ** विशिष्ट मान नहीं है ** भविष्यवाणी –

+0

इस तथ्य को अनदेखा कर रहा है कि कॉलम को घोषित किया गया है 'tinyint (1) 'वही गैर विशिष्टता' WHERE रद्द = सत्य' के लिए मामला होगा। –

3

भले ही यह एक सूचकांक उपयोग कर रहा है, सूचकांक (मानो या न मानो) आपकी क्वेरी धीमा कर सकता है। यह थोड़ा अजीब है, लेकिन यह सूचकांक चयन से संबंधित है। यह आमतौर पर प्रकार बुलियन के कॉलम में प्रस्तुत किया जाता है। ।

ऐसा लगता है कि descrbed है:।

"कैसे एक क्षेत्र के विभिन्न मान रहे हैं यह 0-1, से एक नंबर, हालांकि आप भी एक प्रतिशत के रूप में कर सकते है 1 का मान , या 100% का मतलब है कि क्षेत्र में प्रत्येक मान अद्वितीय है "

यह विचार करना आवश्यक है क्योंकि:

"MySQL का मूल्य-आधारित अनुकूलक है। इसका मतलब है कि MySQL की गणना करने के विभिन्न तरीकों की लागत की गणना करता है और फिर सबसे सस्ता विकल्प चुनता है। खैर, लागत की गणना एक अचूक विज्ञान है। तो एक अनुमान लिया जाता है, और अनुमान कभी कभी गलत है "

सादा सरल:।

डेटा आप देख रहे हैं (उदाहरण के लिए एक ही मूल्य का कम या ज्यादा 20% है , रद्द अपनी मेज का 40% है) तो, यह सिर्फ एक मेज स्कैन करने के लिए आसान है

संपादित करें:।

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

इस पर एक नज़र डालें:

+0

आपके उत्तर के लिए धन्यवाद। मैं अब समझता हूँ। भले ही सवाल अभी भी बनी हुई है। "var1 = false" से अलग नहीं "var var1" कैसे आते हैं? – Phoenix

+0

आप सही हैं, क्षमा करें। मैंने जवाब संपादित किया। – santiagobasulto

1
SELECT * 
FROM 
(SELECT 1 AS C, 0 AS X UNION ALL 
SELECT 2 AS C, 1 AS X UNION ALL 
SELECT 3 AS C, 2 AS X) T 
WHERE X=true 

रिटर्न

'2', '1' 

और

SELECT * 
FROM 
(SELECT 1 AS C, 0 AS X UNION ALL 
SELECT 2 AS C, 1 AS X UNION ALL 
SELECT 3 AS C, 2 AS X) T 
WHERE X 

रिटर्न

'2', '1' 
'3', '2' 

तो ऐसा लगता है कि पहले मामले में trueलिए डाली हो जाता है 0 और फिर एक तलाश योग्य भविष्यवाणी में उपयोग किया जाता है जबकि दूसरे मामले में कॉलम मान को पूरी तरह से कास्ट किया जाता है। लागू आम तौर पर एक शर्त को असंभव बनाते हैं।

WHERE canceled = true साथ आपकी क्वेरी के लिए समझाने की योजना को देखते हुए तो ऐसा लगता है कि यह भी एक के रूप में canceled पर सूचकांक पर विचार नहीं कर सकते

+----+-------------+--------------+------+---------------+----------+---------+-------+------+-----------------------------+ 
| id | select_type | table  | type | possible_keys | key | key_len | ref | rows |   Extra   | 
+----+-------------+--------------+------+---------------+----------+---------+-------+------+-----------------------------+ 
| 1 | SIMPLE  | reservations | ref | canceled  | canceled |  1 | const | 1 | Using where; Using filesort | 
+----+-------------+--------------+------+---------------+----------+---------+-------+------+-----------------------------+ 

देता है जबकि WHERE canceled के लिए आप

+----+-------------+--------------+------+---------------+-----+---------+-----+------+-----------------------------+ 
| id | select_type | table  | type | possible_keys | key | key_len | ref | rows |   Extra   | 
+----+-------------+--------------+------+---------------+-----+---------+-----+------+-----------------------------+ 
| 1 | SIMPLE  | reservations | ALL |    |  |   |  | 2 | Using where; Using filesort | 
+----+-------------+--------------+------+---------------+-----+---------+-----+------+-----------------------------+ 

मिल इस मामले में संभावित विकल्प।

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