মাইএসকিউএল-এ NULL মান সহ কলামগুলির জন্য সূচীগুলি কীভাবে ডিজাইন করবেন?


11

আমার কাছে ৪০ মিলিয়ন এন্ট্রি সহ একটি ডাটাবেস রয়েছে এবং নীচের WHEREধারাটিতে কোয়েরি চালাতে চাই

...
WHERE
  `POP1` IS NOT NULL 
  && `VT`='ABC'
  && (`SOURCE`='HOME')
  && (`alt` RLIKE '^[AaCcGgTt]$')
  && (`ref` RLIKE '^[AaCcGgTt]$')
  && (`AA` RLIKE '^[AaCcGgTt]$')
  && (`ref` = `AA` || `alt` = `AA`)
LIMIT 10 ;

POP1এটি একটি ফ্লোট কলাম যা নুলও হতে পারে। POP1 IS NOT NULLএন্ট্রিগুলির প্রায় 50% বাদ দেওয়া উচিত, এ কারণেই আমি এটি শুরুতে রেখেছি। অন্যান্য সমস্ত শর্তাবলী কেবলমাত্র প্রান্তিকভাবে সংখ্যা হ্রাস করে।

অন্যগুলির মধ্যে, আমি একটি সূচক ডিজাইন করেছি pop1_vt_source, যা মনে হয় না এটি ব্যবহৃত হয়, যখন vtপ্রথম কলাম হিসাবে একটি সূচক ব্যবহৃত হয়। কি ব্যাখ্যা-আউটপুট:

| id | select_type | table | type | possible_keys                          | key                 | key_len | ref         | rows     | Extra       |
|  1 | SIMPLE      | myTab | ref  | vt_source_pop1_pop2,pop1_vt_source,... | vt_source_pop1_pop2 | 206     | const,const | 20040021 | Using where |

pop1প্রথম কলাম হিসাবে সূচকটি কেন ব্যবহার করা হচ্ছে না? কারণ NOTবা NULLসাধারণ কারণে । আমি কীভাবে আমার সূচকগুলির নকশা এবং কোথায় ক্লোজের উন্নতি করতে পারি? এমনকি 10 টি এন্ট্রি সীমাবদ্ধ করার পরেও, কোয়েরিতে 30 সেকেন্ডের বেশি সময় লাগে, যদিও সারণীতে প্রথম 100 এন্ট্রিগুলিতে 10 টি ম্যাচ থাকা উচিত।

উত্তর:


10

এটি হ'ল NOT NULL:

CREATE TEMPORARY TABLE `myTab` (`notnul` FLOAT, `nul` FLOAT);
INSERT INTO `myTab` VALUES (1, NULL), (1, 2), (1, NULL), (1, 2), (1, NULL), (1, 2), (1, NULL), (1, 2), (1, NULL), (1, 2), (1, NULL), (1, 2);
SELECT * FROM `myTab`;

দেয়:

+--------+------+
| notnul | nul  |
+--------+------+
|      1 | NULL |
|      1 |    2 |
|      1 | NULL |
|      1 |    2 |
|      1 | NULL |
|      1 |    2 |
|      1 | NULL |
|      1 |    2 |
|      1 | NULL |
|      1 |    2 |
|      1 | NULL |
|      1 |    2 |
+--------+------+

সূচক তৈরি করুন:

CREATE INDEX `notnul_nul` ON `myTab` (`notnul`, `nul`);
CREATE INDEX `nul_notnul` ON `myTab` (`nul`, `notnul`);

SHOW INDEX FROM `myTab`;

দেয়:

+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name   | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| myTab |          1 | notnul_nul |            1 | notnul      | A         |          12 |     NULL | NULL   | YES  | BTREE      |         |               |
| myTab |          1 | notnul_nul |            2 | nul         | A         |          12 |     NULL | NULL   | YES  | BTREE      |         |               |
| myTab |          1 | nul_notnul |            1 | nul         | A         |          12 |     NULL | NULL   | YES  | BTREE      |         |               |
| myTab |          1 | nul_notnul |            2 | notnul      | A         |          12 |     NULL | NULL   | YES  | BTREE      |         |               |
+-------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+

এখন নির্বাচিতদের ব্যাখ্যা করুন। মনে হচ্ছে মাইএসকিউএল সূচকটি ব্যবহার করে, এমনকি আপনি ব্যবহার করলেও NOT NULL:

EXPLAIN SELECT * FROM `myTab` WHERE `notnul` IS NOT NULL;
+----+-------------+-------+-------+---------------+------------+---------+------+------+--------------------------+ 
| id | select_type | table | type  | possible_keys | key        | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+---------------+------------+---------+------+------+--------------------------+ 
|  1 | SIMPLE      | myTab | index | notnul_nul    | notnul_nul | 10      | NULL |   12 | Using where; Using index |
+----+-------------+-------+-------+---------------+------------+---------+------+------+--------------------------+


EXPLAIN SELECT * FROM `myTab` WHERE `nul` IS NOT NULL;
+----+-------------+-------+-------+---------------+------------+---------+------+------+--------------------------+
| id | select_type | table | type  | possible_keys | key        | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+---------------+------------+---------+------+------+--------------------------+
|  1 | SIMPLE      | myTab | range | nul_notnul    | nul_notnul | 5       | NULL |    6 | Using where; Using index |
+----+-------------+-------+-------+---------------+------------+---------+------+------+--------------------------+

তবে, তুলনা করার সময় NOT NULLএবং NULL, মনে হয় যে মাইএসকিউএল অন্যান্য সূচকগুলি ব্যবহার করার সময় পছন্দ করে NOT NULL। যদিও এটি স্পষ্টত কোনও তথ্য যোগ করে না। এটি কারণ মাইএসকিউএল NOT NULLআপনি টাইপ-কলামে দেখতে পারেন এমন একটি পরিসীমা হিসাবে ব্যাখ্যা করে । আমি নিশ্চিত না যদি কোনও কর্মক্ষেত্র থাকে:

EXPLAIN SELECT * FROM `myTab` WHERE `nul` IS NULL && notnul=2;
+----+-------------+-------+------+-----------------------+------------+---------+-------------+------+--------------------------+
| id | select_type | table | type | possible_keys         | key        | key_len | ref         | rows | Extra                    |
+----+-------------+-------+------+-----------------------+------------+---------+-------------+------+--------------------------+
|  1 | SIMPLE      | myTab | ref  | notnul_nul,nul_notnul | notnul_nul | 10      | const,const |    1 | Using where; Using index |
+----+-------------+-------+------+-----------------------+------------+---------+-------------+------+--------------------------+


EXPLAIN SELECT * FROM `myTab` WHERE `nul` IS NOT NULL && notnul=2;
+----+-------------+-------+-------+-----------------------+------------+---------+------+------+--------------------------+
| id | select_type | table | type  | possible_keys         | key        | key_len | ref  | rows | Extra                    |
+----+-------------+-------+-------+-----------------------+------------+---------+------+------+--------------------------+
|  1 | SIMPLE      | myTab | range | notnul_nul,nul_notnul | notnul_nul | 10      | NULL |    1 | Using where; Using index |
+----+-------------+-------+-------+-----------------------+------------+---------+------+------+--------------------------+

আমি মনে করি মাইএসকিউএলে আরও ভাল বাস্তবায়ন হতে পারে, কারণ NULLএটি একটি বিশেষ মান। সম্ভবত বেশিরভাগ লোকই NOT NULLমূল্যবোধে আগ্রহী ।


3

ইস্যুটি নুল মান নয়। এটি সূচকের নির্বাচকতা। আপনার উদাহরণে, এর নির্বাচনিতা ন্যায়বিচারের source, pop1নির্বাচন করার চেয়ে ভাল pop1। এটি whereক্লজের শর্তগুলির বেশিরভাগটি কভার করে তাই পৃষ্ঠাগুলি হিট কমার সম্ভাবনা বেশি।

আপনি ভাবতে পারেন যে সারিগুলির সংখ্যা 50% হ্রাস করা যথেষ্ট, তবে এটি আসলে তা নয়। একটি whereদফায় সূচকের সুবিধা হ'ল পঠনের সংখ্যা হ্রাস করা। যদি কোনও পৃষ্ঠাতে গড়ে কমপক্ষে একটি নন-নুল মান সহ একটি রেকর্ড থাকে তবে সূচকটি ব্যবহার করার কোনও লাভ নেই। এবং, যদি প্রতি পৃষ্ঠায় 10 টি রেকর্ড থাকে তবে প্রায় প্রতিটি পৃষ্ঠায় সেই রেকর্ডগুলির মধ্যে একটি থাকবে।

আপনি একটি সূচক চেষ্টা করতে পারেন (pop1, vt, source)। অপ্টিমাইজারটি এটি বাছাই করা উচিত।

শেষ পর্যন্ত, যদিও, যদি whereধারাটি রেকর্ডগুলি হারিয়ে রাখে - কোনও নিয়ম নেই তবে আসুন 20% বলি - তবে সূচক সম্ভবত সাহায্য করবে না। একটি ব্যতিক্রম হবে যখন সূচীতে কোয়েরির জন্য প্রয়োজনীয় সমস্ত কলাম রয়েছে । তারপরে এটি প্রতিটি রেকর্ডের জন্য ডেটা পৃষ্ঠা না নিয়েই কোয়েরিটি সন্তুষ্ট করতে পারে।

এবং, যদি কোনও সূচক ব্যবহার করা হয় এবং চূড়ান্ততা বেশি থাকে, তবে সূচকের সাথে পারফরম্যান্সটি এটি ছাড়া সম্পাদনের চেয়ে খারাপ হতে পারে।


আমি মনে করি এটি আসলেই এমন ব্যাপ্তি যা পার্থক্য সৃষ্টি করে (আমার উত্তর দেখুন)। যদিও আমি মনে করি এটি মাইএসকিউএলে আরও ভালভাবে প্রয়োগ করা যেতে পারে, যেহেতু বেশিরভাগ লোক NOT NULLকলামে আগ্রহী ।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.