LinQ to SQL Skip分页效率问题

时间:2021-09-12 20:49:22
LinQ to SQL对获取到的数据进行分页显示时,使用的是
int COUNT_IN_ONE_PAGE = 10;
var items = db.Students;
items = items.Skip(() => (pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE)
在pageNum较小时,耗时在3000毫秒左右,但是
当pageNum较大,例如1200,则需要19000+毫秒,这个时间让页面等待很长时间,
请问有什么办法能够提高速度么?让pageNum在1200时,也能在3000毫秒左右处理完成。

22 个解决方案

#1


你比如的例子不对吧,如果按你这个,没按照任何条件查询过滤,那么直接就是聚集索引,不可能那么慢

你应该查的是你的索引设置问题

#2


linq to sql 会将最终的语法转换成sql语句  由数据库引擎执行。

var items = db.Students;
items = items.Skip(() => (pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE)
-》这两段代码,每次进行分页操作都会将所有的Students数据存到匿名变量里,改成:
var list =  db.Students.Skip(() => (pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE);  测试


PS:个人观点,欢迎指正。

#3


引用 1 楼 starfd 的回复:
你比如的例子不对吧,如果按你这个,没按照任何条件查询过滤,那么直接就是聚集索引,不可能那么慢

你应该查的是你的索引设置问题


的确没有条件查询过滤,不过有一次内连接,然后按照入学时间排序了,大概语句是:
var item = var items = (from p in m_db.student
                         join q in m_db.Teacher
                         on p.id equals q.StudentID
                         orderby p.time descending
                         select new Info
                          {
                           }

原来的语句因为设计到了公司的内容,不方便直接给出来,我给出的算是一个类似的情况。

#4


引用 2 楼 duanzi_peng 的回复:
linq to sql 会将最终的语法转换成sql语句  由数据库引擎执行。

var items = db.Students;
items = items.Skip(() => (pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE)
-》这两段代码,每次进行分页操作都会将所有的Students数据存到匿名变量里,改成:
var list =  db.Students.Skip(() => (pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE);  测试


PS:个人观点,欢迎指正。


您好,谢谢你的回复,我在改成如您所说情况之后,编译出错了
LinQ to SQL Skip分页效率问题

是不是我哪里没有写好?

#5


这条linq取决于你对应的provider的翻译,如果数据库支持row number,那么就很快,否则就很慢。

#6


引用 4 楼 zhoul_831 的回复:
Quote: 引用 2 楼 duanzi_peng 的回复:

linq to sql 会将最终的语法转换成sql语句  由数据库引擎执行。

var items = db.Students;
items = items.Skip(() => (pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE)
-》这两段代码,每次进行分页操作都会将所有的Students数据存到匿名变量里,改成:
var list =  db.Students.Skip(() => (pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE);  测试


PS:个人观点,欢迎指正。


您好,谢谢你的回复,我在改成如您所说情况之后,编译出错了
LinQ to SQL Skip分页效率问题

是不是我哪里没有写好?

你贴的代码是自己写的么?,skip 接收的是一个int类型,不需要匿名委托。

#7


引用 6 楼 duanzi_peng 的回复:
Quote: 引用 4 楼 zhoul_831 的回复:

Quote: 引用 2 楼 duanzi_peng 的回复:

linq to sql 会将最终的语法转换成sql语句  由数据库引擎执行。

var items = db.Students;
items = items.Skip(() => (pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE)
-》这两段代码,每次进行分页操作都会将所有的Students数据存到匿名变量里,改成:
var list =  db.Students.Skip(() => (pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE);  测试


PS:个人观点,欢迎指正。


您好,谢谢你的回复,我在改成如您所说情况之后,编译出错了
LinQ to SQL Skip分页效率问题

是不是我哪里没有写好?

你贴的代码是自己写的么?,skip 接收的是一个int类型,不需要匿名委托。

是刚才看到你的回复后照样子改的

#8


引用 5 楼 caozhy 的回复:
这条linq取决于你对应的provider的翻译,如果数据库支持row number,那么就很快,否则就很慢。


我是用的SQL Server 2008 版本,这个对row_number用法支持么?

#9


引用 8 楼 zhoul_831 的回复:
Quote: 引用 5 楼 caozhy 的回复:

这条linq取决于你对应的provider的翻译,如果数据库支持row number,那么就很快,否则就很慢。


我是用的SQL Server 2008 版本,这个对row_number用法支持么?

用sql server profiler(sql server management studio的tools菜单下有)拦截调用的sql,看下就知道了。

#10


引用 9 楼 caozhy 的回复:
Quote: 引用 8 楼 zhoul_831 的回复:

Quote: 引用 5 楼 caozhy 的回复:

这条linq取决于你对应的provider的翻译,如果数据库支持row number,那么就很快,否则就很慢。


我是用的SQL Server 2008 版本,这个对row_number用法支持么?

用sql server profiler(sql server management studio的tools菜单下有)拦截调用的sql,看下就知道了。


刚才查了一下,是支持的,但是还是慢,我google上查了一下说是因为Skip的时候,会根据我的排序遍历一遍,所以时间会长,Linq官方没有什么解决办法吗?

#11


是在不行,就写动态sql
var q=db.database.sqlquery<Students>(sql语句);

#12


引用 11 楼 hanjun0612 的回复:
是在不行,就写动态sql
var q=db.database.sqlquery<Students>(sql语句);


最后没办法的时候再这么干吧,因为动态条件挺多,用SQL语句来写太长而且不好维护

#13


on p.id equals q.StudentID
                         orderby p.time descending

先确认你的join有没有索引
然后确认你的time有没有索引

#14


引用 13 楼 starfd 的回复:
on p.id equals q.StudentID
                         orderby p.time descending

先确认你的join有没有索引
然后确认你的time有没有索引


time有索引,Join的值没有索引,然后刚才看了一下, Join的值因为建表的时候类型写成了nvarchar(max),所以现在没法建索引了

#15


实在一点还是写存储过程吧 LinQ to SQL Skip分页效率问题

#16


要看下生成的语句,

#17


引用 16 楼 xiaoxiangqing 的回复:
要看下生成的语句,


是的!

了解需要如何调试关键节点,胜过只知道写代码。

#18


引用 楼主 zhoul_831 的回复:
LinQ to SQL对获取到的数据进行分页显示时,使用的是
int COUNT_IN_ONE_PAGE = 10;
var items = db.Students;
items = items.Skip(() => (pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE)
在pageNum较小时,耗时在3000毫秒左右,但是
当pageNum较大,例如1200,则需要19000+毫秒,这个时间让页面等待很长时间,
请问有什么办法能够提高速度么?让pageNum在1200时,也能在3000毫秒左右处理完成。


分页没有排序字段,我还头一次见!!!!!

就算现在的新生代程序员不学数据库,不了解索引优化,但ef分页的基本用法总该是要看看的吧!!!

#19


尼玛,skip里面居然放了委托。。。。

唉。。。。

#20


你需要了解真实的、SQL Server数据库执行的查询。数据库只应该返回一页数据,而不能返回大量垃圾数据到内存。

#21


不要单纯按照学习(其实跟分不清楚真懂还是抄袭)的方式设计程序,我们看一个程序员实际的开发能力,其实看调试、测试,而不是只看编程。那么对这个问题,你肯定首先要贴出来发送给 SQL Server 的最终的 sql 查询命令语句,只有当一个返回几十行数据(一页数据)的查询需要执行20秒钟时才应该纠结数据库方面的设计问题(例如索引、表结构)问题。重点是要自动自觉地贴出真实的 sql 语句。

#22


db.Students.Skip((pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE); 

#1


你比如的例子不对吧,如果按你这个,没按照任何条件查询过滤,那么直接就是聚集索引,不可能那么慢

你应该查的是你的索引设置问题

#2


linq to sql 会将最终的语法转换成sql语句  由数据库引擎执行。

var items = db.Students;
items = items.Skip(() => (pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE)
-》这两段代码,每次进行分页操作都会将所有的Students数据存到匿名变量里,改成:
var list =  db.Students.Skip(() => (pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE);  测试


PS:个人观点,欢迎指正。

#3


引用 1 楼 starfd 的回复:
你比如的例子不对吧,如果按你这个,没按照任何条件查询过滤,那么直接就是聚集索引,不可能那么慢

你应该查的是你的索引设置问题


的确没有条件查询过滤,不过有一次内连接,然后按照入学时间排序了,大概语句是:
var item = var items = (from p in m_db.student
                         join q in m_db.Teacher
                         on p.id equals q.StudentID
                         orderby p.time descending
                         select new Info
                          {
                           }

原来的语句因为设计到了公司的内容,不方便直接给出来,我给出的算是一个类似的情况。

#4


引用 2 楼 duanzi_peng 的回复:
linq to sql 会将最终的语法转换成sql语句  由数据库引擎执行。

var items = db.Students;
items = items.Skip(() => (pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE)
-》这两段代码,每次进行分页操作都会将所有的Students数据存到匿名变量里,改成:
var list =  db.Students.Skip(() => (pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE);  测试


PS:个人观点,欢迎指正。


您好,谢谢你的回复,我在改成如您所说情况之后,编译出错了
LinQ to SQL Skip分页效率问题

是不是我哪里没有写好?

#5


这条linq取决于你对应的provider的翻译,如果数据库支持row number,那么就很快,否则就很慢。

#6


引用 4 楼 zhoul_831 的回复:
Quote: 引用 2 楼 duanzi_peng 的回复:

linq to sql 会将最终的语法转换成sql语句  由数据库引擎执行。

var items = db.Students;
items = items.Skip(() => (pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE)
-》这两段代码,每次进行分页操作都会将所有的Students数据存到匿名变量里,改成:
var list =  db.Students.Skip(() => (pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE);  测试


PS:个人观点,欢迎指正。


您好,谢谢你的回复,我在改成如您所说情况之后,编译出错了
LinQ to SQL Skip分页效率问题

是不是我哪里没有写好?

你贴的代码是自己写的么?,skip 接收的是一个int类型,不需要匿名委托。

#7


引用 6 楼 duanzi_peng 的回复:
Quote: 引用 4 楼 zhoul_831 的回复:

Quote: 引用 2 楼 duanzi_peng 的回复:

linq to sql 会将最终的语法转换成sql语句  由数据库引擎执行。

var items = db.Students;
items = items.Skip(() => (pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE)
-》这两段代码,每次进行分页操作都会将所有的Students数据存到匿名变量里,改成:
var list =  db.Students.Skip(() => (pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE);  测试


PS:个人观点,欢迎指正。


您好,谢谢你的回复,我在改成如您所说情况之后,编译出错了
LinQ to SQL Skip分页效率问题

是不是我哪里没有写好?

你贴的代码是自己写的么?,skip 接收的是一个int类型,不需要匿名委托。

是刚才看到你的回复后照样子改的

#8


引用 5 楼 caozhy 的回复:
这条linq取决于你对应的provider的翻译,如果数据库支持row number,那么就很快,否则就很慢。


我是用的SQL Server 2008 版本,这个对row_number用法支持么?

#9


引用 8 楼 zhoul_831 的回复:
Quote: 引用 5 楼 caozhy 的回复:

这条linq取决于你对应的provider的翻译,如果数据库支持row number,那么就很快,否则就很慢。


我是用的SQL Server 2008 版本,这个对row_number用法支持么?

用sql server profiler(sql server management studio的tools菜单下有)拦截调用的sql,看下就知道了。

#10


引用 9 楼 caozhy 的回复:
Quote: 引用 8 楼 zhoul_831 的回复:

Quote: 引用 5 楼 caozhy 的回复:

这条linq取决于你对应的provider的翻译,如果数据库支持row number,那么就很快,否则就很慢。


我是用的SQL Server 2008 版本,这个对row_number用法支持么?

用sql server profiler(sql server management studio的tools菜单下有)拦截调用的sql,看下就知道了。


刚才查了一下,是支持的,但是还是慢,我google上查了一下说是因为Skip的时候,会根据我的排序遍历一遍,所以时间会长,Linq官方没有什么解决办法吗?

#11


是在不行,就写动态sql
var q=db.database.sqlquery<Students>(sql语句);

#12


引用 11 楼 hanjun0612 的回复:
是在不行,就写动态sql
var q=db.database.sqlquery<Students>(sql语句);


最后没办法的时候再这么干吧,因为动态条件挺多,用SQL语句来写太长而且不好维护

#13


on p.id equals q.StudentID
                         orderby p.time descending

先确认你的join有没有索引
然后确认你的time有没有索引

#14


引用 13 楼 starfd 的回复:
on p.id equals q.StudentID
                         orderby p.time descending

先确认你的join有没有索引
然后确认你的time有没有索引


time有索引,Join的值没有索引,然后刚才看了一下, Join的值因为建表的时候类型写成了nvarchar(max),所以现在没法建索引了

#15


实在一点还是写存储过程吧 LinQ to SQL Skip分页效率问题

#16


要看下生成的语句,

#17


引用 16 楼 xiaoxiangqing 的回复:
要看下生成的语句,


是的!

了解需要如何调试关键节点,胜过只知道写代码。

#18


引用 楼主 zhoul_831 的回复:
LinQ to SQL对获取到的数据进行分页显示时,使用的是
int COUNT_IN_ONE_PAGE = 10;
var items = db.Students;
items = items.Skip(() => (pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE)
在pageNum较小时,耗时在3000毫秒左右,但是
当pageNum较大,例如1200,则需要19000+毫秒,这个时间让页面等待很长时间,
请问有什么办法能够提高速度么?让pageNum在1200时,也能在3000毫秒左右处理完成。


分页没有排序字段,我还头一次见!!!!!

就算现在的新生代程序员不学数据库,不了解索引优化,但ef分页的基本用法总该是要看看的吧!!!

#19


尼玛,skip里面居然放了委托。。。。

唉。。。。

#20


你需要了解真实的、SQL Server数据库执行的查询。数据库只应该返回一页数据,而不能返回大量垃圾数据到内存。

#21


不要单纯按照学习(其实跟分不清楚真懂还是抄袭)的方式设计程序,我们看一个程序员实际的开发能力,其实看调试、测试,而不是只看编程。那么对这个问题,你肯定首先要贴出来发送给 SQL Server 的最终的 sql 查询命令语句,只有当一个返回几十行数据(一页数据)的查询需要执行20秒钟时才应该纠结数据库方面的设计问题(例如索引、表结构)问题。重点是要自动自觉地贴出真实的 sql 语句。

#22


db.Students.Skip((pageNum - 1) * COUNT_IN_ONE_PAGE).Take(COUNT_IN_ONE_PAGE);