我现在有一张大数据的表大概1亿条数据,需要每次查询出100w条,我测试了下要是直接通过where id between 1 and 1000000 查询需要用1分半-2分钟,特别慢,能不能开启多个线程,类似于10w条10w条这样的查,这样查效率能不能快一点,或者有什么更好的办法,请指教
你们公司的数据库服务器真好,你们公司的老板真厉害,请你做这事真是牛刀杀鸡了,屈才啊。
一次性的工作,不是天天每次查100W啊,老大就是嫌慢,让优化
@自由の风:
1、别往多线程上想。
2、这事得找DBA。
3、一次性的工作,优化是没有意义的,当然你们公司人力资源冗余也是可以理解的。
@爱编程的大叔: 有的公司说不定都没有DBA
@MrNice: 我的意思是,你只能在数据库服务器上想,
1、分区、分表、分库、添加索引,添加视图(静态编译有助于性能),使用存储过程(有助于性能)
2、增加CPU\内存,换SSD硬盘
数据库服务器外的对于速度无意义。
只是你可以选择在数据库服务器不忙的时候慢慢做而已。
你自己开多线程就行了呀,保证每个线程使用独立的Connection
好吧,我试试
这事多线程只会更慢。
@自由の风: 搜了一下,博客园有类似的问题,你看看 sql多线程查询
@爱编程的大叔: 你让他测试一下就知道了,我没测试过,但是感觉不会有提高
@爱编程的大叔: 多线程肯定会更慢,但是如果数据需要处理就可以平衡一下了,比如还要对数据进行计算或是汇总等等也许还好一点,不过他这数据量也太大了,不管怎么做,高并发下,会影响其它用户,买的虚拟空间CPU占用一般有限制。
多线程毫无意义,因为你的表只有一个,如果你先对表进行拆分,那么这个时候多线程有可能会排上用场。
一亿条数据一个表,有点夸张,看你是用between这种方式,可以尝试加索引。
个人觉得横向表拆分才是比较有意义的。
好的,我试着拆表
@自由の风: 还有另外一种做法,数据预处理。
在当前库中,就这个大表查询好,插入到当前库的一个新表中,这个过程可以用job来跑。然后其他地方用的时候,就使用新表的数据(100w),百万级的查询,一般来说不会太慢。
从性能上来说,查询必须分页(例如每页显示100条),但可以给出匹配的总条目(100W),查询匹配总数应该不会太慢。另外感觉一次查询100W条这界面也显示老长了,而且用户还要滚动才能继续浏览,用户体验也不好呀)
不是查询给人显示看的,查出来要再插入别的表的,插入这边我用sqlbulkcopy做了,就是感觉查询的时候慢,不知道怎么能快一点
@自由の风:
这样呀,sqlbulkcopy已经比一般的方法快多了,主要是数据量太大。多线程说不定可以
你好,请问MrNice 给的链接测试了吗?效率有没有提升?
我拆成10W条10W条弄,和之前效果相差不大
@自由の风: 谢谢,有没有试过50W条弄?如果创建多次数据库连接应该也是需要花时间的。
@火悬崖: 差别不大,还是想想别的方法吧
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Threading; using System.Data.Sql; using System.Data.SqlClient; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { //以每10000条为一个分隔点 //增加一列ID,最好是自动增长,然后设置为聚集索引 string cmdstr1 = @"select * from D where ID>0 and ID<5"; string cmdstr2 = @"select * from D where ID>5 and ID<10"; //第一个线程 Task.Factory.StartNew(new Action(() => { NewMethod(cmdstr1); })); //第二个线程 Task.Factory.StartNew(new Action(() => { NewMethod(cmdstr2); })); Console.ReadKey(); } private static void NewMethod(string cmdstr1) { SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=mydb;Persist Security Info=True;User ID=sa;Password=12314;MultipleActiveResultSets=True"); con.Open(); SqlCommand cmd = new SqlCommand(cmdstr1, con); IAsyncResult result = cmd.BeginExecuteReader(new AsyncCallback((ar) => { }), cmd); SqlDataReader dataReader = cmd.EndExecuteReader(result); if (dataReader.HasRows) { if (dataReader.Read()) { Console.WriteLine(dataReader["LastTime"]); } } con.Close(); } } }
恩,谢谢了,多线程的写法已经实现了,但是效果不大,已经不从这方面考虑了。
@自由の风: 不过你可以试试 我的方法,说不定有惊喜哦
@田麦成: 恩,我会试试的
这事就像@爱编程的大叔 说的,只能从数据库服务器上想方法,你再多线程,就一个服务器,快不到哪去。想想分库分表之类的。
本来我也想用个多线程查库的,看了楼上的,现在彻底放弃