MySQL पूर्ण रूप से गलत नहीं है?


18

कृपया इस तालिका को देखें:

mysql> desc s_p;

+-------------------------+------------------+------+-----+---------+----------------+    
| Field                   | Type             | Null | Key | Default | Extra          |
+-------------------------+------------------+------+-----+---------+----------------+
| id                      | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
| s_pid                   | int(10) unsigned | YES  | MUL | NULL    |                |
| sm_id                   | int(10) unsigned | YES  | MUL | NULL    |                |
| m_id                    | int(10) unsigned | YES  |     | NULL    |                |
| created                 | datetime         | YES  |     | NULL    |                |
| s_date                  | datetime         | YES  |     | NULL    |                |
| estimated_date          | datetime         | YES  | MUL | NULL    |                |
+-------------------------+------------------+------+-----+---------+----------------+

अब इन प्रश्नों पर एक नज़र डालें:

mysql> select count(*) from s_p where estimated_date is null;
+----------+
| count(*) |
+----------+
|   190580 |
+----------+
1 row in set (0.05 sec)

mysql> select count(*) from s_p where estimated_date is not null;
+----------+
| count(*) |
+----------+
|    35640 |
+----------+
1 row in set (0.07 sec)

mysql> select count(*) from s_p;
+----------+
| count(*) |
+----------+
|  1524785 |
+----------+

ऊपर की गणनाएँ मेल नहीं खा रही हैं। जबकि मेरी समझ के अनुसार:

काउंट के साथ IS NULLऔर काउंट विद IS NOT NULLकाउंट तब बराबर होना चाहिए, जब क्लॉज के बिना गणना की जाए।

यहाँ क्या हो रहा है पर कोई विचार?

================================================== =

अपडेट 17 फरवरी 2012 को

चूंकि, मैंने पाया कि बहुत से लोग इस तरह के मूल्यों के बारे में पूछ रहे हैं जो वर्तमान में अनुमानित_डेट के प्रकार हैं। यहाँ जवाब है:

mysql> select distinct date(estimated_date) from s_p;

+----------------------+
| date(estimated_date) |
+----------------------+
| NULL                 |
| 2012-02-17           |
| 2012-02-20           |
| 2012-02-21           |
| 2012-02-22           |
| 2012-02-23           |
| 2012-02-24           |
| 2012-02-27           |
| 2012-02-28           |
+----------------------+
9 rows in set (0.42 sec)

जैसा कि आप ऊपर देख सकते हैं अनुमानित या तो NULL या एक मान्य डेटाइम मान है। कोई शून्य या खाली तार नहीं हैं ""।

क्या यह (मूल मुद्दा) हो सकता है अगर अनुमानित_डैट पर सूचकांक में कुछ समस्या है / है?

================================================== =

अपडेट 18 फरवरी 2012 को

यहां शो क्रिएट टेबल आउटपुट है:

 | s_p | CREATE TABLE `s_p` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `s_id` int(10) unsigned DEFAULT NULL,
  `sm_id` int(10) unsigned DEFAULT NULL,
  `m_id` int(10) unsigned DEFAULT NULL,
  `created` datetime DEFAULT NULL,
  `estimated_date` datetime DEFAULT NULL,
   PRIMARY KEY (`id`),
   KEY `sm_id` (`sm_id`),
   KEY `estimated_date_index` (`estimated_date`) USING BTREE,
  ) ENGINE=InnoDB AUTO_INCREMENT=1602491 DEFAULT CHARSET=utf8 |

फिर, मैं यहाँ केवल अनुमानित_दाह पर सूचकांक पर संदेह कर सकता हूँ।

इसके अलावा, mysql सर्वर संस्करण 5.5.12 है।


3
जब तक तालिका को 3 प्रश्नों को चलाने और उसके दौरान नई पंक्तियों के साथ नहीं खिलाया जा रहा है, तब तक ऐसा नहीं हो सकता है!
ypercube y

6
क्या आप निश्चित हैं कि आप ए select count(*)और नहीं कर रहे हैं select count(estimated_date)? ये दोनों अलग-अलग परिणाम लौटाएंगे क्योंकि NULLs को अनदेखा किया जाता है यदि केवल वही चीज़ है जिसे आप गिन रहे हैं।

6
मुझे यकीन नहीं है कि निम्नलिखित MySQL में काम करेगा या नहीं, लेकिन क्या आप रनिंग की कोशिश कर सकते हैं: SELECT COUNT(*),SUM(CASE WHEN estimated_date IS NULL THEN 1 ELSE 0 END),SUM(CASE WHEN estimated_date IS NOT NULL THEN 1 ELSE 0 END) from s_p- जो कि एक बार में सभी काउंट प्राप्त करें।
डेमियन_इन_अनबेलियर

1
क्या आपके द्वारा चलाए जा रहे सटीक प्रश्न हैं?
gbn

4
इसके अलावा, अगर यह MyISAM है, तो क्या आप इस CHECK TABLEपर चल सकते हैं ? बेतहाशा बड़ी पूर्ण पंक्ति गिनती को ध्यान में रखते हुए , मुझे लगता है कि DELETEकहीं पागल हो गया है।
नल्लाथिरल

जवाबों:


6

क्या आपके पास कुछ शून्य तिथियाँ हैं? 0000-00-00 00:00:00MySQL द्वारा एक साथ संतुष्ट करने के लिए डेटाटाइम मानों पर विचार किया जाता हैis null और is not null:

steve@steve@localhost > create temporary table _tmp (a datetime not null);
Query OK, 0 rows affected (0.02 sec)

steve@steve@localhost > insert into _tmp values ('');
Query OK, 1 row affected, 1 warning (0.00 sec)

Warning (Code 1264): Out of range value for column 'a' at row 1
steve@steve@localhost > select a from _tmp where a is null;
+---------------------+
| a                   |
+---------------------+
| 0000-00-00 00:00:00 |
+---------------------+
1 row in set (0.00 sec)

steve@steve@localhost > select a from _tmp where a is not null;
+---------------------+
| a                   |
+---------------------+
| 0000-00-00 00:00:00 |
+---------------------+
1 row in set (0.00 sec)

देखें: http://bugs.mysql.com/bug.php?id=940

इसे "बग नहीं" के रूप में वर्गीकृत किया गया है। वे वर्कअराउंड का सुझाव देते हैं: सख्त मोड का उपयोग करें, जो प्रविष्टि चेतावनी को एक त्रुटि में बदल देगा।

यह सब कहने के बाद, यह अकेले आपको प्राप्त होने वाले परिणामों में जंगली भिन्नता की व्याख्या नहीं कर सकता है ( is nullऔर is not nullगणना का योग अप्रतिबंधित गणना से अधिक होना चाहिए) ...


बग तब प्रकट होता है जब DATEया DATETIMEके रूप में परिभाषित किया जाता है NOT NULL। यहां प्रश्न में, स्तंभ को अशक्त के रूप में परिभाषित किया गया है। हालाँकि यह बग, MySQL को केवल सख्त मोड में चलाने का एक और कारण है।
ypercube y 20

मैंने अनुमानित पोस्ट को मौजूदा मानों को अनुमानित_डेट कॉलम में दिखाने के लिए अपडेट किया है। इसमें 0000-00-00 या खाली तार "" नहीं है।
user1213259

1
@yper या एक अलग DBMS लेने का कारण ...
ErikE

1
@ एरिक: वह, कभी-कभी, एक विकल्प नहीं है। और आपको हमेशा एनओटीएचआर डीबीएमएस लेने के कारण मिलेंगे, जो भी आप के साथ काम कर रहे हैं।
ypercube y

FYI करें ToadSQL से पता चलता है कि 0000-00-00 00:00:00 {null} के रूप में, आगे पानी में कीचड़ हो रहा है! कितना बुरा सपना। एफटीआर हमारे पास हमारे समस्या स्तंभ पर एक सूचकांक नहीं है। यह 5.6.15-लॉग पर है।
मुस्कुराते हुए

3

@ypercube:

मुझे हाल ही में पूछा गया था कि क्या मुझे लगा कि रिग्रेस बग "SELECT COUNT (DISTINCT) क्रैश हो जाता है जब WHO ऑपरेंड प्राथमिक कुंजी या यूनिक इंडेक्स में होता है" इस की जड़ में हो सकता है।

यहाँ मेरा जवाब है (मूल रूप से यहाँ):

http://www.chriscalender.com/?p=315&cpage=1#comment-1460

मुझे नहीं लगता कि यह वही बग है। यह बग दुर्घटनाग्रस्त होने के बारे में अधिक है, और इसके लिए विशेष रूप से एक SELECT COUNT (DISTINCT) की आवश्यकता होती है, साथ ही WHERE का संचालन प्राथमिक कुंजी या अनन्य अनुक्रमणिका में होता है।

आपके बग / समस्या में DISTINCT नहीं है, यह क्रैश नहीं हो रहा है, और डेटाटाइम कॉलम पर अनुक्रमणिका प्राथमिक कुंजी नहीं है और न ही अद्वितीय है। हालांकि, यह कफ से थोड़ा अजीब है, इसलिए मैंने कुछ खोज की, और इस बग में भाग गया, जिसमें शामिल होने / संबंधित होने की अधिक संभावना है:

http://bugs.mysql.com/bug.php?id=60105

वास्तव में, इसे "बग नहीं" के रूप में निर्दिष्ट किया गया है, लेकिन यह दिखाता है कि आप कैसे अजीब व्यवहार में भाग ले सकते हैं, जब आपके पास दिनांक / डेटाइम '0000-00-00 ′ के साथ है और IS NULL और IS NOT NULL का उपयोग कर रहा है।

मुझे आश्चर्य है कि अगर आपके पास इनमें से कोई भी 00 0000-00-00 could पंक्तियां हैं जो कि गिनती को प्रभावित कर सकती हैं?

बग रिपोर्ट में टिप्पणी करने वाले देव इस पृष्ठ का भी उल्लेख करते हैं:

यदि ऐसा नहीं है, तो मैं निश्चित रूप से नवीनतम 5.5 पर 5.5.21 (2/22/2012 तक) के उन्नयन और इसे आज़माने की सलाह दूंगा, क्योंकि यह 5.5.12 के बाद से 9 महीने (और 9 रिलीज़) रहा है। जारी किया गया।

ध्यान दें कि आपको तालिका (और डेटा) को डंप करने और इसे दूसरे परीक्षण उदाहरण में आयात करने में सक्षम होना चाहिए, बस इसे परीक्षण करने के लिए। इस तरह आप एक उत्पादन मशीन को प्रभावित नहीं करते हैं, और आप एक परीक्षण उदाहरण मिनटों में स्थापित कर सकते हैं।

फिर, क्या इससे कोई फर्क नहीं पड़ता, फिर भी आप कुछ अन्य वस्तुओं का परीक्षण करने की स्थिति में होंगे, जैसे कि शायद यह देखने के लिए कि क्या यह एक वैश्विक एक है, या सिर्फ InnoDB के लिए विशिष्ट है, यह देखने के लिए तालिका को MyISAM में बदल दें।

या, मैंने देखा कि 'अनुमानित_डेट' पर सूचकांक था:

कुंजी estimated_date_index( estimated_date) BTREE का उपयोग करना

"उपयोग करने के लिए ध्यान दें"। शायद इसका उपयोग बिना किसी प्रयास के करें और देखें कि क्या आप अभी भी वही व्यवहार देखते हैं। (या केवल परीक्षण करने के लिए सूचकांक को पूरी तरह से हटा दें .. यह समस्या को कम करने में मदद करेगा)।

उम्मीद है की यह मदद करेगा।


1

क्वेरी का प्रयास करें

select * from s_p where estimated_date is null and estimated_date is not null limit 5;

मुझे नहीं लगता कि आप समझते हैं कि सवाल क्या है।

2
उपरोक्त क्वेरी गलत व्यवहार पंक्तियों को दिखाएगी जिससे आप समाधान पा सकते हैं।

1
यदि वह क्वेरी किसी भी पंक्तियों को वापस करती है, तो मैं आपके डेटा की अखंडता के बारे में गंभीर रूप से चिंतित हूं ।
नल्लाथिरल

@Naltharial यह मेरा डेटा नहीं है, ऊपर दिया गया सवाल अजीब आउटपुट देता है।

mysql> s_p से * select करें जहां अनुमानित_डलेट शून्य है और अनुमानित_डलेट शून्य सीमा 5 नहीं है; खाली सेट (0.00 सेकंड)
user1213259

1

मुझे टेबल लेआउट में कुछ दिलचस्प दिखाई देता है जो 'मुझे मतगणना की तरह महसूस नहीं होता है।' मैं जो कहने वाला हूं वह केवल एक कूबड़ है।

आपने इस क्वेरी को पहले चलाया था

select distinct date(estimated_date) from s_p;

इसे COUNT / GROUP BY के रूप में चलाएं

select count(1) rowcount,date(estimated_date) from s_p group by date(estimated_date);

तुम्हें पता है कि आप के लिए देख रहे थे मायने रखता है मिला।

फिर भी, NULL और NOT NULL की गणना सही ढंग से क्यों होगी? फिर, यह सिर्फ एक शिक्षित अनुमान है।

आपके पास कॉलम estimated_dateअनुक्रमणित है। यहाँ मैं तुम्हें कोशिश करना चाहता हूँ:

SHOW INDEX FROM s_p;
SHOW INDEX FROM s_p;
SHOW INDEX FROM s_p;
SHOW INDEX FROM s_p;

वह टाइपो नहीं है। मैं चाहता हूं कि आप SHOW INDEX FROM s_p;चार (4) बार दौड़ें । को देखो Cardinalityस्तंभ। s_pInnoDB में तालिका के बाद से , मुझे उम्मीद है कि कार्डिनैलिटी कॉलम हर बार अलग होगा। क्यों?

इनटीडीबी को बीटीआरईई पेज प्रविष्टियों के माध्यम से गिनकर कार्डिनलिटी मान प्राप्त होता है। अपने सिस्टम चर innodb_stats_on_metadata की जाँच करें । इसे सक्षम किया जाना चाहिए। यदि यह पहले से ही सक्षम है, तो इसे अक्षम करें और चीजों को बेहतर बनाने के लिए अपने मूल प्रश्नों को फिर से चलाएँ। केवल एक लंबे परिणाम के रूप में इस !!!

इसलिए इन प्रश्नों के बजाय:

select count(*) from s_p where estimated_date is null;
select count(*) from s_p where estimated_date is not null;

प्रयत्न

select count(estimated_date) from s_p;

यह आपको गैर-अशक्त अनुमानित_डेट के साथ पंक्तियों की गिनती देना चाहिए।

ISNULL फ़ंक्शन का उपयोग करके आप इस ब्रूट फ़ोर्स क्वेरी के साथ प्रयोग करना चाहते हैं :

select count(*) rowcount,isnull(estimated_date) IsItNull
from s_p group by isnull(estimated_date);

मुझे आशा है कि ये सुझाव मदद करेंगे !!!


-4

यह अपेक्षित है। एक स्तंभ के लिए जो अशक्त है 0 == NULL = "" और इसी तरह। तो पहला चेक वास्तव में उन पंक्तियों को लौटाता है जहाँ कोई तिथि निर्धारित नहीं की गई थी या "0 / NULL" के अनुरूप माना जाता है


2
0के बराबर कभी नहीं है NULL। जब तक आप ओरेकल के साथ काम नहीं कर रहे हैं तब तक खाली स्ट्रिंग ( '') समान नहीं है NULL
ypercube y
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.