添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

SqlSugar版本:SqlSugarCore 5.1.3.30

数据库:PostgreSQL 9

C# .net6 web站点


问题描述:这是一个很神奇的现象,每天新增的记录数大约在(2-3万行之间),直接执行SQL无延时卡顿现象,分页异步查询分区表当查询结果大于1.5W行时前N页加载很慢,且分2种情况


1、默认查询当天数据,当查询结果行数不多时响应时间正常,大于1.5万行时开始第1页卡,数量越多从第1页起卡的页数越多,如:超过2万行时,前5页卡,页码大于5就不卡了。

2、改变条件查今天之前的历史数据时(查一天的),第一次打开页面时至少卡10秒以上,数据加载完成后,再次刷新或翻页响应效率为第1种情况。


PostgreSQL分区表,结构如下

CREATE TABLE IF NOT EXISTS x_record
    id serial8 NOT NULL,
    add_time timestamptz,
    --此处省略6个integer,1个varcahr,13个bigint,1个timestamptz
) PARTITION BY RANGE (add_time);
CREATE TABLE x_record_202308 PARTITION OF x_record FOR VALUES FROM ('2023-08-01 00:00:00+08') TO ('2023-09-01 00:00:00+08');
CREATE INDEX IF NOT EXISTS x_record_202308_idx_add_time ON x_record_202308(add_time);
CREATE  INDEX  IF  NOT  EXISTS  x_record_202308_idx_id  ON  x_record_202308(id);

以下为C#查询代码,查询时间范围1天,每页20行

var exp = Expressionable.Create<x_record>()
	.And(a => SqlFunc.Between(a.add_time, fromTime, toTime))
	.ToExpression();
var list = await db.Queryable<x_record>()
	.Where(eWhere)
	.OrderBy(a => a.id, OrderByType.Desc)
	.Select(a => new x_view()
		id = a.id ,
		add_time = a.add_time,
		//省略部分字段
	}).ToPageListAsync(page, 20);


解决方法:改用直接执行SQL再绑定就很丝滑了

string tmpSql = db.Queryable<x_record>()
	.Where(eWhere)
	.OrderBy(a => a.id, OrderByType.Desc)
	.Select(a => new x_view()
		id = a.id ,
		add_time = a.add_time,
		//省略部分字段
	}).ToSqlString();
var list = await db.Ado.SqlQueryAsync<x_view>(tmpSql + $"limit 20 offset {((page - 1) * 20)};");


@fate sta :刚才我重新写了查询案例:2种写法的效率是不一样的

1、前N页卡顿的写法

db.xxxx.ToPageListAsync(page, limit);

查询20页时间:

total:16433,page:1,耗时:2309.9048

total:16433,page:2,耗时:1553.7535

total:16433,page:3,耗时:1581.5697

total:16433,page:4,耗时:1549.5327

total:16433,page:5,耗时:1652.3516

total:16433,page:6,耗时:1614.657

total:16433,page:7,耗时:1571.5268

total:16433,page:8,耗时:1686.1091

total:16433,page:9,耗时:1768.5345

total:16433,page:10,耗时:1660.1226

total:16433,page:11,耗时:1740.2945

total:16433,page:12,耗时:1710.5694

total:16433,page:13,耗时:1779.3872

total:16433,page:14,耗时:1822.8966

total:16433,page:15,耗时:1641.3461

total:16433,page:16,耗时:1554.6926

total:16433,page:17,耗时:1823.3728

total:16433,page:18,耗时:79.5095

total:16433,page:19,耗时:71.8547

total:16433,page:20,耗时:59.9317


2、以下写法效率正常

db.xxxxx.Skip((page - 1) * limit).Take(limit).ToListAsync();

查询20页时间:

total:16433,page:1,耗时:585.4071

total:16433,page:2,耗时:67.9149

total:16433,page:3,耗时:64.731

total:16433,page:4,耗时:72.2917

total:16433,page:5,耗时:110.8405

total:16433,page:6,耗时:78.7364

total:16433,page:7,耗时:88.1795

total:16433,page:8,耗时:92.128

total:16433,page:9,耗时:97.117

total:16433,page:10,耗时:99.5275

total:16433,page:11,耗时:105.6536

total:16433,page:12,耗时:130.1762

total:16433,page:13,耗时:129.8083

total:16433,page:14,耗时:214.9252

total:16433,page:15,耗时:183.8991

total:16433,page:16,耗时:108.8862

total:16433,page:17,耗时:100.3811

total:16433,page:18,耗时:253.7756

total:16433,page:19,耗时:166.4153

total:16433,page:20,耗时:177.1487


db.xxxxx.Skip((page - 1) * limit).Take(limit).ToListAsync();

在不查Count情况下等于

ToPageLis 底层是一模一样的没有任何差异的地方


@fate sta :剔除Count效率一样的不行,确定是ToPageList这个用法导致的效率问题,是否返回count问题都在,同步异步都有的,刚才还试了普通表,也有一样的情况。

可能跟字段数量多少也有关系,同样的表结构复制4个字段没复现,有时间我整理复现列子


不好意思最近有点忙,就没做案例,并且无意间找到为啥直接执行SQL不卡的原因了,分区表查询的时候,《分区键》作为查询条件时使用传参方式查询时无法触发《分区约束排除》导致查询所有子表导致效率极低,而直接使用SQL不会有这个问题