mysql 单表扫描大数据测试

2013-11-18 15:16:52 +08:00
 yakczh
环境
Intel(R) Core(TM) i3-3210 CPU @ 3.20GHz
DDR3 mem 4g
ST500DM002-1BD142 500g
xp sp3
mysqld 5.6.13

建表

CREATE TABLE `test100w` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`subject` varchar(200) CHARACTER SET utf8 NOT NULL,
`content` text CHARACTER SET utf8 NOT NULL,
`ctime` int(10) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

插入随机数据
import MySQLdb
from time import *
from time import clock
from random import *
start=clock()

now = time()

try:
conn=MySQLdb.connect(host='localhost',user='root',passwd='display',db='bench',port=3306,charset='utf8')
cur=conn.cursor()
i=1
while i< 100*10000:
rand=randint(10000, 99999)
sql = "insert into test100w(subject, content,ctime) values ('%s', '%s',%d)" % ("testdata_"+str(rand),"somedata_"+str(rand),now )
#query="select * from test200w where subject like '%%%s' " % str(rand)
print sql
try :
count=cur.execute(sql)
conn.commit()
except Exception,e:
print e
conn.rollback()

i=i+1

cur.close()

conn.close()
except MySQLdb.Error,e:
print "Mysql Error %d: %s" % (e.args[0], e.args[1])
finish=clock()
print (finish-start)/1000000


查询
import MySQLdb
from time import clock
from random import *
start=clock()


try:
conn=MySQLdb.connect(host='localhost',user='root',passwd='display',db='bench',port=3306,charset='utf8')
cur=conn.cursor()
rand=randint(10000, 99999)
query="select * from test100w where subject like '%%%s' " % str(rand)
print query
count=cur.execute(query)
print 'there has %s rows record' % count
result=cur.fetchone()
print result
#print 'ID: %s info %s' % result
#results=cur.fetchmany(5)
#for r in results:
# print r
cur.close()
conn.close()
except MySQLdb.Error,e:
print "Mysql Error %d: %s" % (e.args[0], e.args[1])
finish=clock()
print (finish-start)/1000000

结果
100w 1.45214545424e-06
200w 2.183407109e-06
400w 4.3417384053e-06
4248 次点击
所在节点    Python
16 条回复
vietor
2013-11-18 15:27:18 +08:00
你想证明用mysql做“主题查询足够了”,不需要“分词索引”那些额外系统?
yakczh
2013-11-18 15:48:26 +08:00
@vietor 是要做分表,看一个表分多大合适才不会影响到正常的业务应用
sohoer
2013-11-18 17:52:50 +08:00
范围很重要
likexian
2013-11-18 18:19:25 +08:00
xp,400万,大数据,想什么呢?洗洗睡吧
yakczh
2013-11-18 19:09:13 +08:00
@likexian 这个测试只是找一个分成单表的数据桶的大小阈值,实际的数据有14亿,类似象全国省,市,县,区这种行政区划的查询,从任一级都有查询的需求,从姓名,关键性字段,业务时间段, 保证查询能在3-5秒能有响应
icyalala
2013-11-18 19:35:48 +08:00
@yakczh
这么说是国企咯~ 怎么不用oracle?
yakczh
2013-11-18 20:35:42 +08:00
@icyalala  oracle也装不了14亿吧
victor
2013-11-18 21:37:44 +08:00
@yakczh 14亿?是我们的户口数据么?
yakczh
2013-11-18 23:34:31 +08:00
@victor 恭喜你,答对了
soli
2013-11-19 09:07:17 +08:00
有结果,没结论。
yakczh
2013-11-19 10:10:55 +08:00
@soli 结果就是分表的单表容量保持在 500w以下
yakczh
2013-11-19 10:30:34 +08:00
总数据容量 /500 =表数 , 每个表当作一个存储单元 ,维护一个映射表,查询和插入,更新都通过隐射找到对应的存储单元
wangchen
2013-11-19 14:30:41 +08:00
@yakczh 你的查询语句中的`like` 部分,如果以% 开头,是无法使用索引的。

另外,还是要从应用的实际需要去考虑存储、查询要使用什么技术。比如是频繁写,还是频繁读?读是全文检索,还是结构化查询?
yakczh
2013-11-19 15:00:48 +08:00
@wangchen 就是测试无索引的全表扫秒的极限值,有索引的情况千差万别,跟索引的数据分布有关系, 不同的数据分布各不相同,只有这个全表扫描情况下才有确切的数值
实际应用中有 根据姓名来模糊搜索的,比如姓张,张王这种的,而且比较多,查询时间限制在3s之内有结果
bombless
2013-11-21 07:37:43 +08:00
查询为主的就好办了……自古以来解决大量数据查询的不二法则就是多浪费存储空间……
最简单的想法就是,根据搜索的类型的需要,每次有新的搜索类型的时候就根据那个类型的特点来划分数据存储的位置把数据分组存放,搜索的时候在确定有目标数据的地方搜就可以了~
yakczh
2013-11-21 09:25:46 +08:00
@bombless 这种是索引的思路,根据索引能查找数据这种情况基本可以忽略,但不幸的是,不是所有数据都能完全索引的,即使是在根据索引找到的结果集范围中,最后还是要落实到Handler read rnd next的查找中,而这个搜索用的时间与索引查找的时间不是一个数量级,就跟光纤到户的最后一公里一样,最终影响整个链路总时间的最大因素是由最后一段接入的速度决定的,如果能找到不用索引仅靠扫描表就能找到的数据量阈值,就能决定存储数据(其中会有一部分是不能索引的)的容量要保持在多少范围内

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/89691

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX