在StoneDB中,数据包分为以下几类:
通过对数据包的划分,知识网格技术过滤掉不相关的数据包,读取相关的数据包和可疑的数据包。其中相关的数据包不需要解压缩,只读取元数据,不会发生IO,可疑的数据包需要解压缩,会发生IO。
1)创建表t_user
CREATE TABLE t_user(
id INT NOT NULL AUTO_INCREMENT,
first_name VARCHAR(10) NOT NULL,
last_name VARCHAR(10) NOT NULL,
sex VARCHAR(5) NOT NULL,
score INT NOT NULL,
copy_id INT NOT NULL,
PRIMARY KEY (`id`),
key idx_lastname(last_name)
) engine=STONEDB;
2)创建存储过程
DELIMITER //
create PROCEDURE add_user(in num INT)
BEGIN
DECLARE rowid INT DEFAULT 0;
DECLARE firstname CHAR(1);
DECLARE name1 CHAR(1);
DECLARE name2 CHAR(1);
DECLARE lastname VARCHAR(3) DEFAULT '';
DECLARE sex CHAR(1);
DECLARE score CHAR(2);
WHILE rowid < num DO
SET firstname = SUBSTRING('赵钱孙李周吴郑王林杨柳刘孙陈江阮侯邹高彭徐',FLOOR(1+21*RAND()),1);
SET name1 = SUBSTRING('一二三四五六七八九十甲乙丙丁静景京晶名明铭敏闵民军君俊骏天田甜兲恬益依成城诚立莉力黎励',ROUND(1+43*RAND()),1);
SET name2 = SUBSTRING('一二三四五六七八九十甲乙丙丁静景京晶名明铭敏闵民军君俊骏天田甜兲恬益依成城诚立莉力黎励',ROUND(1+43*RAND()),1);
SET sex=FLOOR(0 + (RAND() * 2));
SET score= FLOOR(40 + (RAND() *60));
SET rowid = rowid + 1;
IF ROUND(RAND())=0 THEN
SET lastname =name1;
END IF;
IF ROUND(RAND())=1 THEN
SET lastname = CONCAT(name1,name2);
END IF;
insert INTO t_user(first_name,last_name,sex,score,copy_id) VALUES (firstname,lastname,sex,score,rowid);
END WHILE;
END //
DELIMITER ;
3)插入数据
call add_user(10000000);
4)创建表t_user_innodb
create table t_user_innodb like t_user;
insert into t_user_innodb select * from t_user;
alter table t_user_innodb engine=innodb;
SQL的语义逻辑是对字段 first_name 进行分组统计,在StoneDB中,元数据信息记录在元数据节点,如果能通过元数据节点读取到元数据,就不需要解压缩数据包,不发生IO。
在InnoDB中,表的统计信息记录在mysql.innodb_table_stats,优化器根据表和索引的统计信息,生成一个最优的执行计划,然后执行SQL。分别在InnoDB与StoneDB执行,通过SQL profile观察读取IO的情况。
注:为规避缓存的影响,每组测试前重启数据库实例。
mysql> set profiling=on;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> select first_name,count(*) from t_user_innodb group by first_name;
+------------+----------+
| first_name | count(*) |
+------------+----------+
| 侯 | 476424 |
| 刘 | 475764 |
| 吴 | 475979 |
| 周 | 475891 |
| 孙 | 950444 |
| 彭 | 476632 |
| 徐 | 476219 |
| 李 | 475521 |
| 杨 | 476026 |
| 林 | 477289 |
| 柳 | 476250 |
| 江 | 476623 |
| 王 | 475119 |
| 赵 | 476529 |
| 邹 | 476852 |
| 郑 | 476379 |
| 钱 | 476829 |
| 阮 | 476336 |
| 陈 | 476746 |
| 高 | 476148 |
+------------+----------+
20 rows in set (8.62 sec)
mysql> show profiles;
+----------+------------+-------------------------------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+-------------------------------------------------------------------+
| 1 | 8.61591075 | select first_name,count(*) from t_user_innodb group by first_name |
+----------+------------+-------------------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> show profile cpu,block io for query 1;
+----------------------+----------+----------+------------+--------------+---------------+
| Status | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out |
+----------------------+----------+----------+------------+--------------+---------------+
| starting | 0.000149 | 0.000059 | 0.000083 | 0 | 0 |
| checking permissions | 0.000027 | 0.000011 | 0.000015 | 0 | 0 |
| Opening tables | 0.048181 | 0.003919 | 0.007952 | 608 | 0 |
| init | 0.000036 | 0.000014 | 0.000021 | 0 | 0 |
| System lock | 0.000022 | 0.000009 | 0.000013 | 0 | 0 |
| optimizing | 0.000017 | 0.000007 | 0.000010 | 0 | 0 |
| statistics | 0.000029 | 0.000012 | 0.000016 | 0 | 0 |
| preparing | 0.000022 | 0.000009 | 0.000013 | 0 | 0 |
| Creating tmp table | 0.000045 | 0.000019 | 0.000027 | 0 | 0 |
| Sorting result | 0.000016 | 0.000007 | 0.000009 | 0 | 0 |
| executing | 0.000014 | 0.000005 | 0.000008 | 0 | 0 |
| Sending data | 8.566974 | 6.905969 | 0.772964 | 873888 | 0 |
| Creating sort index | 0.000144 | 0.000164 | 0.000037 | 64 | 0 |
| end | 0.000014 | 0.000012 | 0.000003 | 32 | 0 |
| query end | 0.000028 | 0.000038 | 0.000009 | 0 | 0 |
| removing tmp table | 0.000019 | 0.000015 | 0.000003 | 0 | 0 |
| query end | 0.000012 | 0.000010 | 0.000002 | 0 | 0 |
| closing tables | 0.000031 | 0.000025 | 0.000006 | 0 | 0 |
| freeing items | 0.000032 | 0.000027 | 0.000006 | 0 | 0 |
| logging slow query | 0.000067 | 0.000054 | 0.000012 | 0 | 8 |
| cleaning up | 0.000035 | 0.000028 | 0.000006 | 0 | 0 |
+----------------------+----------+----------+------------+--------------+---------------+
21 rows in set, 1 warning (0.00 sec)
从SQL profile可知,SQL在InnoDB执行的过程中,发生IO的阶段有Opening tables、Sending data、Creating sort index、end,其中Opening tables是每张表第一次加载都会经历的,可排除讨论。重点关注Sending data部分,它表示在执行器的任意阶段,通常是存储引擎层与Server层的IO交互过程。
mysql> set profiling=on;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> select first_name,count(*) from t_user group by first_name;
+------------+----------+
| first_name | count(*) |
+------------+----------+
| 赵 | 476529 |
| 徐 | 476219 |
| 王 | 475119 |
| 阮 | 476336 |
| 柳 | 476250 |
| 侯 | 476424 |
| 孙 | 950444 |
| 郑 | 476379 |
| 高 | 476148 |
| 林 | 477289 |
| 邹 | 476852 |
| 彭 | 476632 |
| 李 | 475521 |
| 吴 | 475979 |
| 刘 | 475764 |
| 钱 | 476829 |
| 周 | 475891 |
| 杨 | 476026 |
| 陈 | 476746 |
| 江 | 476623 |
+------------+----------+
20 rows in set (0.59 sec)
mysql> show profiles;
+----------+------------+------------------------------------------------------------+
| Query_ID | Duration | Query |
+----------+------------+------------------------------------------------------------+
| 1 | 0.59069975 | select first_name,count(*) from t_user group by first_name |
+----------+------------+------------------------------------------------------------+
1 row in set, 1 warning (0.00 sec)
mysql> show profile cpu,block io for query 1;
+----------------------+----------+----------+------------+--------------+---------------+
| Status | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out |
+----------------------+----------+----------+------------+--------------+---------------+
| starting | 0.000160 | 0.000066 | 0.000089 | 0 | 0 |
| checking permissions | 0.000027 | 0.000011 | 0.000015 | 0 | 0 |
| Opening tables | 0.011405 | 0.003718 | 0.007688 | 0 | 240 |
| System lock | 0.000385 | 0.000163 | 0.000222 | 0 | 0 |
| init | 0.000050 | 0.000021 | 0.000028 | 0 | 0 |
| optimizing | 0.000143 | 0.000061 | 0.000082 | 0 | 0 |
| update multi-index | 0.000052 | 0.000022 | 0.000030 | 0 | 0 |
| aggregation | 0.578315 | 2.639504 | 0.981471 | 0 | 8 |
| query end | 0.000069 | 0.000043 | 0.000026 | 0 | 0 |
| closing tables | 0.000035 | 0.000021 | 0.000013 | 0 | 0 |
| freeing items | 0.000034 | 0.000021 | 0.000013 | 0 | 0 |
| cleaning up | 0.000027 | 0.000017 | 0.000010 | 0 | 0 |
+----------------------+----------+----------+------------+--------------+---------------+
12 rows in set, 1 warning (0.00 sec)
从SQL profile可知,SQL在StoneDB执行的过程中,只在Opening tables阶段发生IO。其它阶段没有发生IO,说明相关数据包是不需要解压缩的,通过元数据得到。
SQL的语义逻辑是查询一行数据,StoneDB可以通过知识网格技术过滤掉不相关的数据包,由于只返回一行数据,最终只能找到可疑的数据包,然后解压缩可疑的数据包,最终得到这一行数据。InnoDB还是根据统计信息生成一个最优的执行计划去执行SQL。
mysql> set profiling=on;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> select count(*) from t_user_innodb where first_name='柳' and copy_id=9968888;
+----------+
| count(*) |
+----------+
| 1 |
+----------+
1 row in set (3.20 sec)
mysql> show profile cpu,block io for query 1;
+----------------------+----------+----------+------------+--------------+---------------+
| Status | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out |
+----------------------+----------+----------+------------+--------------+---------------+
| starting | 0.000170 | 0.000072 | 0.000092 | 0 | 0 |
| checking permissions | 0.000030 | 0.000013 | 0.000016 | 0 | 0 |
| Opening tables | 0.024121 | 0.004351 | 0.008638 | 800 | 0 |
| init | 0.000049 | 0.000021 | 0.000027 | 0 | 0 |
| System lock | 0.000019 | 0.000008 | 0.000011 | 0 | 0 |
| optimizing | 0.000022 | 0.000010 | 0.000012 | 0 | 0 |
| statistics | 0.000030 | 0.000013 | 0.000016 | 0 | 0 |
| preparing | 0.000026 | 0.000012 | 0.000015 | 0 | 0 |
| executing | 0.000013 | 0.000005 | 0.000007 | 0 | 0 |
| Sending data | 3.169882 | 2.755171 | 0.389367 | 534176 | 0 |
| end | 0.000069 | 0.000050 | 0.000018 | 0 | 0 |
| query end | 0.000029 | 0.000022 | 0.000008 | 0 | 0 |
| closing tables | 0.000031 | 0.000023 | 0.000009 | 0 | 0 |
| freeing items | 0.000035 | 0.000025 | 0.000009 | 0 | 0 |
| cleaning up | 0.000038 | 0.000028 | 0.000010 | 0 | 0 |
+----------------------+----------+----------+------------+--------------+---------------+
15 rows in set, 1 warning (0.00 sec)
mysql> set profiling=on;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> select count(*) from t_user where first_name='柳' and copy_id=9968888;
+----------+
| count(*) |
+----------+
| 1 |
+----------+
1 row in set (0.01 sec)
mysql> show profile cpu,block io for query 1;
+----------------------+----------+----------+------------+--------------+---------------+
| Status | Duration | CPU_user | CPU_system | Block_ops_in | Block_ops_out |
+----------------------+----------+----------+------------+--------------+---------------+
| starting | 0.000173 | 0.000081 | 0.000086 | 0 | 0 |
| checking permissions | 0.000026 | 0.000013 | 0.000013 | 0 | 0 |
| Opening tables | 0.010228 | 0.009385 | 0.000843 | 0 | 240 |
| System lock | 0.000232 | 0.000113 | 0.000119 | 0 | 0 |
| init | 0.000045 | 0.000021 | 0.000022 | 0 | 0 |
| optimizing | 0.000144 | 0.000071 | 0.000074 | 0 | 0 |
| update multi-index | 0.003694 | 0.002027 | 0.006428 | 0 | 0 |
| aggregation | 0.000191 | 0.000093 | 0.000098 | 0 | 16 |
| query end | 0.000020 | 0.000010 | 0.000010 | 0 | 0 |
| closing tables | 0.000029 | 0.000014 | 0.000015 | 0 | 0 |
| freeing items | 0.000033 | 0.000016 | 0.000017 | 0 | 0 |
| cleaning up | 0.000027 | 0.000013 | 0.000013 | 0 | 0 |
+----------------------+----------+----------+------------+--------------+---------------+
12 rows in set, 1 warning (0.00 sec)
从SQL profile可知,SQL在StoneDB执行的过程中,在aggregation阶段发生IO。
综上所述:
我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?
给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我正在使用ruby1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\
这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife
我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案
我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que
我需要检查DateTime是否采用有效的ISO8601格式。喜欢:#iso8601?我检查了ruby是否有特定方法,但没有找到。目前我正在使用date.iso8601==date来检查这个。有什么好的方法吗?编辑解释我的环境,并改变问题的范围。因此,我的项目将使用jsapiFullCalendar,这就是我需要iso8601字符串格式的原因。我想知道更好或正确的方法是什么,以正确的格式将日期保存在数据库中,或者让ActiveRecord完成它们的工作并在我需要时间信息时对其进行操作。 最佳答案 我不太明白你的问题。我假设您想检查
我的日期格式如下:"%d-%m-%Y"(例如,今天的日期为07-09-2015),我想看看是不是在过去的七天内。谁能推荐一种方法? 最佳答案 你可以这样做:require"date"Date.today-7 关于ruby-检查日期是否在过去7天内,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/32438063/
这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下