Advertisement
mitrakov

MySQL: indexing

Jan 23rd, 2018
377
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
MySQL 6.77 KB | None | 0 0
  1. -- MySQL Server 5.7.17
  2. -- 1. Let's create a table
  3. CREATE TABLE `student` (
  4.     `student_id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'primary key',
  5.     `name` VARCHAR(64) NOT NULL COMMENT 'student name',
  6.     `birthday` DATE NOT NULL COMMENT 'day of birthday',
  7.     `sex` ENUM('Male','Female') NOT NULL COMMENT 'sex: male/female',
  8.     `admission_year` SMALLINT(5) UNSIGNED NOT NULL COMMENT 'year of admission',
  9.     `teach_time` SMALLINT(5) UNSIGNED NOT NULL COMMENT 'teach time, in semesters',
  10.     `faculty_id` BIGINT(20) UNSIGNED NOT NULL COMMENT 'reference to faculty table',
  11.     PRIMARY KEY (`student_id`),
  12.     CONSTRAINT `FK_student_faculty` FOREIGN KEY (`faculty_id`) REFERENCES `faculty` (`faculty_id`) ON UPDATE CASCADE ON DELETE CASCADE
  13. ) COMMENT='student table' COLLATE='utf8_general_ci' ENGINE=InnoDB;
  14.  
  15.  
  16.  
  17. -- 2. Add a procedure to fill it with test data
  18. DELIMITER $$
  19. CREATE PROCEDURE fillStudent(IN NumRows INT) LANGUAGE SQL CONTAINS SQL NOT DETERMINISTIC COMMENT 'procedure to fill student table'
  20.   BEGIN
  21.     DECLARE i INT DEFAULT 1;
  22.     START TRANSACTION;
  23.       WHILE i <= NumRows DO
  24.         INSERT INTO `student` (`name`, `birthday`, `sex`, `admission_year`, `teach_time`, `faculty_id`)
  25.         VALUES (
  26.           MD5(RAND()),
  27.           NOW() - INTERVAL FLOOR(RAND() * 14000) DAY,
  28.           IF (RAND() > 0.5, 'Male', 'Female'),
  29.           FLOOR(2000 + 10*RAND()),
  30.           FLOOR(8 + 10*RAND()),
  31.           CEIL(RAND() * (SELECT COUNT(*) FROM faculty))
  32.         );
  33.         SET i = i + 1;
  34.       END WHILE;
  35.     COMMIT;
  36.   END$$
  37. DELIMITER ;
  38.  
  39.  
  40.  
  41. -- 3. Let's insert 10M rows (may take a long time!)
  42. CALL fillStudent(10000000);
  43. /* Affected rows: 0  Found rows: 0  Warnings: 0  Duration for 1 query: 00:21:39 */
  44. -- Table size: 895 mb
  45.  
  46.  
  47.  
  48. -- 4. Let's check O(N) time
  49. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student`;
  50. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 18,346 sec. */
  51.  
  52.  
  53.  
  54. -- 5. Also let's check MySQL created index for Foreign Keys automatically:
  55. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `faculty_id` = 3;
  56. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 0,608 sec. */
  57.  
  58.  
  59.  
  60. -- 6.1. No indexes:
  61. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `admission_year` = 2000;
  62. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 18,221 sec. */
  63. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `teach_time` = 8;
  64. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 18,720 sec. */
  65. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `admission_year` = 2000 AND `teach_time` = 8;
  66. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 18,627 sec. */
  67. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `admission_year` = 2000 OR `teach_time` = 8;
  68. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 18,033 sec. */
  69.  
  70.  
  71.  
  72. -- 6.2. Indexes: (admission_year)
  73. ALTER TABLE `student` ADD INDEX `idx_student_admission_year` (`admission_year` ASC);
  74.  
  75. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `admission_year` = 2000;
  76. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 0,296 sec. */
  77. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `teach_time` = 8;
  78. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 18,221 sec. */
  79. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `admission_year` = 2000 AND `teach_time` = 8;
  80. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 35,834 sec. */
  81. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `admission_year` = 2000 OR `teach_time` = 8;
  82. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 18,845 sec. */
  83.  
  84.  
  85.  
  86. -- 6.3. Indexes: (admission_year), (teach_time)
  87. ALTER TABLE `student` ADD INDEX `idx_student_teach_time` (`teach_time` ASC);
  88.  
  89. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `admission_year` = 2000;
  90. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 0,296 sec. */
  91. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `teach_time` = 8;
  92. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 0,296 sec. */
  93. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `admission_year` = 2000 AND `teach_time` = 8;
  94. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 0,718 sec. */
  95. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `admission_year` = 2000 OR `teach_time` = 8;
  96. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 51,746 sec. */
  97.  
  98.  
  99.  
  100. -- 6.4. Indexes: (admission_year, teach_time)
  101. ALTER TABLE `student` DROP INDEX `idx_student_admission_year`;
  102. ALTER TABLE `student` DROP INDEX `idx_student_teach_time`;
  103. ALTER TABLE `student` ADD INDEX `idx_student_admission_year_teach_time` (`admission_year` ASC, `teach_time` ASC);
  104.  
  105. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `admission_year` = 2000;
  106. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 0,296 sec. */
  107. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `teach_time` = 8;
  108. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 8,175 sec. */
  109. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `admission_year` = 2000 AND `teach_time` = 8;
  110. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 0,031 sec. */
  111. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `admission_year` = 2000 OR `teach_time` = 8;
  112. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 8,767 sec. */
  113.  
  114.  
  115.  
  116. -- 6.5. Indexes: (admission_year, teach_time), (teach_time)
  117. ALTER TABLE `student` ADD INDEX `idx_student_teach_time` (`teach_time` ASC);
  118.  
  119. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `admission_year` = 2000;
  120. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 0,297 sec. */
  121. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `teach_time` = 8;
  122. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 0,297 sec. */
  123. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `admission_year` = 2000 AND `teach_time` = 8;
  124. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 0,031 sec. */
  125. SELECT SQL_NO_CACHE COUNT(`student_id`) FROM `student` WHERE `admission_year` = 2000 OR `teach_time` = 8;
  126. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 9,251 sec. */
  127.  
  128.  
  129. -- 7. Bonus! Let's modify OR with UNION. Indexes: (admission_year), (teach_time)
  130. SELECT SQL_NO_CACHE SUM(bb) FROM (
  131.   (SELECT COUNT(`student_id`) AS bb FROM `student` WHERE `admission_year` = 2000)
  132.   UNION
  133.   (SELECT COUNT(`student_id`) AS bb FROM `student` WHERE `teach_time` = 8)
  134. ) t;
  135. /* Affected rows: 0  Found rows: 1  Warnings: 0  Duration for 1 query: 0,577 sec. */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement