MySQL社区

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

搜索
查看: 2800|回复: 0
打印 上一主题 下一主题

[存储过程及函数] MySQL 5.6 MRR 的存储过程完美诠释

[复制链接]
跳转到指定楼层
1#
发表于 2013-4-19 11:39:05 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

MySQL 5.6 即将发布, 5.6对优化器方面做了诸多优化。 我这次主要解释MRR(MULTI-RANGE-READ)。

我用存储过程解释了这一过程的改变。大家细心体会去吧。

我们针对语句:
  1. select log_time from person where nick_name = 'Lucy';
复制代码
表结构为:
  1. CREATE TABLE `person` (
  2.   `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  3.   `nick_name` varchar(40) NOT NULL,
  4.   `log_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  5.   PRIMARY KEY (`id`),
  6.   KEY `idx_nick_name` (`nick_name`)
  7. ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1 ;
复制代码
首先是MySQL 5.5
  1. DELIMITER $
  2. USE `ytt`$
  3. DROP PROCEDURE IF EXISTS `sp_range_scan5_5`$
  4. CREATE DEFINER=`admin`@`%` PROCEDURE `sp_range_scan5_5`()
  5. BEGIN
  6.       -- Sample sql statement is below.
  7.       -- select log_time from person where nick_name = 'Lucy';
  8.       DECLARE i INT UNSIGNED DEFAULT 0;
  9.       DECLARE cnt INT UNSIGNED DEFAULT 0;
  10.       SET @result = '';     
  11.       SELECT COUNT(1) INTO cnt FROM person WHERE nick_name = 'Lucy';
  12.      
  13.       loop1:WHILE i < cnt
  14.       DO
  15.         SET @stmt = CONCAT('select id into @v_id from person where nick_name = ''Lucy'' order by nick_name asc limit ',i,',1');
  16.         PREPARE s1 FROM @stmt;
  17.         EXECUTE s1;
  18.       
  19.         SET @result = CONCAT(@result,'select log_time from person where id = @v_id');
  20.         SET @result = CONCAT(@result,' union all ');
  21.         SET i = i + 1;
  22.       END WHILE loop1;
  23.       SET @result = SUBSTR(@result,1,CHAR_LENGTH(@result)-CHAR_LENGTH(' union all '));
  24.       PREPARE s1 FROM @result;
  25.       EXECUTE s1;
  26.       DROP PREPARE s1;
  27.       SET @result = NULL;  
  28.     END$
  29. DELIMITER ;
复制代码


下来是MySQL 5.6
  1. DELIMITER $
  2. USE `ytt`$
  3. DROP PROCEDURE IF EXISTS `sp_range_scan5_6`$
  4. CREATE DEFINER=`admin`@`%` PROCEDURE `sp_range_scan5_6`()
  5. BEGIN
  6.       -- Sample sql statement is below.
  7.       -- select log_time from person where nick_name = 'Lucy';
  8.       DECLARE i INT UNSIGNED DEFAULT 0;
  9.       DECLARE cnt INT UNSIGNED DEFAULT 0;
  10.       DECLARE ids TEXT;   
  11.       SET ids = '';
  12.       SELECT COUNT(1) INTO cnt FROM person WHERE nick_name = 'Lucy';
  13.      
  14.       loop1:WHILE i < cnt
  15.       DO
  16.         SET @stmt = CONCAT('select id into @v_id from person where nick_name = ''Lucy''
  17.          order by nick_name asc limit ',i,',1');
  18.         PREPARE s1 FROM @stmt;
  19.         EXECUTE s1;
  20.         SET ids = CONCAT(ids,@v_id,',');
  21.         SET i = i + 1;
  22.       END WHILE loop1;
  23.       SET ids = CONCAT('(',SUBSTR(ids,1,CHAR_LENGTH(ids)-1),')');
  24.       SET @result = CONCAT('select log_time from person where id in',ids);
  25.       PREPARE s1 FROM @result;
  26.       EXECUTE s1;
  27.       DROP PREPARE s1;
  28.       SET @result = NULL;  
  29.     END$
  30. DELIMITER ;
复制代码
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 分享淘帖 顶 踩
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|申请友链|小黑屋|Archiver|手机版|MySQL社区 ( 京ICP备07012489号   
联系人:周生; 联系电话:13911732319

GMT+8, 2024-4-26 23:49 , Processed in 0.065339 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表