DotNetNext / SqlSugar

.Net aot ORM Fastest ORM Simple Easy VB.NET Sqlite orm Oracle ORM Mysql Orm 虚谷数据库 postgresql ORm SqlServer oRm 达梦 ORM 人大金仓 ORM 神通ORM C# ORM , C# ORM .NET ORM NET5 ORM .NET6 ORM ClickHouse orm QuestDb ,TDengine ORM,OceanBase orm,GaussDB orm ,Tidb orm Object/Relational Mapping
https://www.donet5.com/Home/Doc
MIT License
5.35k stars 1.34k forks source link

您好,不知道是否可以麻烦您封装添加一个,ToPageList 分页的总条目 count 不敏感统计的方法 #960

Closed h619633675 closed 2 years ago

h619633675 commented 3 years ago

您好,我在 postgreSQL/mysql 中实验了一个 demo。 此 demo 的场景为

  1. 数据量大,且需要分页,但是对旧数据数量不那么敏感的时候。
  2. 类似微信/知乎等贴子,只显示 10万加阅读量。

目的是减少每次实时统计 count 计算时间,且数据量较少的时候任然能精确提现条目数,数据量大但是对旧数据数量不那么敏感的时候使用。

下面是一个 demo

        [TestMethod]
        public void SelectCountByClone()
        {
            var db = ConnBuild.Build();
            var queryable = db.Queryable<Table1>()
                .Where(a => a.Idd > 1)
                .OrderBy(a => a.Idd, OrderByType.Desc);

            // 总条目数 ,子查询加快 count 速度,超过 100000 时为取 100000
            // SELECT COUNT(1) FROM (SELECT t.* FROM  (SELECT 1 FROM "table1"   WHERE ( "id" > @Idd0 )  ORDER BY "id" DESC LIMIT 100000 offset 0) t   ) CountTable ;
            var totalNumber = db.Queryable(queryable.Clone().Select("1").Take(100000)).Count();
            Trace.WriteLine(totalNumber);
            // 数据页
            //  SELECT "id","name","email","address" FROM "table1"   WHERE ( "id" > @Idd0 )  ORDER BY "id" DESC LIMIT 10 offset 0;
            var list = queryable.ToPageList(1, 10);
            foreach (var item in list)
            {
                Trace.WriteLine($"id: {item.Idd}, name: {item.Name}");
            }
        }

对于上面的 demo,如果可以的话,麻烦添加一个 ToPageList 函数,在其中有一个参数 maxCountNumber 的限制。

题外话,我尝试在用 explain 模糊统计 sql 的 rows 用作 count, 在 postgreSQL/mysql 数据量较小的时候,都会出现严重偏差,数据量大的时候能有 60%-90% 左右的总条目保有量,所以这个方式我会用在数据量大的时候统计条目数。 所以不知道是否能麻烦作者,看能以什么方式,在数据总条目数不敏感的时候,更好的兼容数据量小和大的 count 统计加速, 直接一步到位就更舒适了。 麻烦大佬了,大佬喝阔落。

h619633675 commented 3 years ago

以下是我关于 EXPLAIN 的补充

        [TestMethod]
        public void SelectCountByClone()
        {
            var db = ConnBuild.Build();
            var queryable = db.Queryable<Table1>()
                .Where(a => a.Idd > 1)
                .OrderBy(a => a.Idd, OrderByType.Desc);

            // 总条目数 ,子查询加快 count 速度,超过 100000 时为取 100000
            // SELECT COUNT(1) FROM (SELECT t.* FROM  (SELECT 1 FROM "table1"   WHERE ( "id" > @Idd0 )  ORDER BY "id" DESC LIMIT 100000 offset 0) t   ) CountTable ;
            var totalNumber = db.Queryable(queryable.Clone().Select("1").Take(100000)).Count();
            Trace.WriteLine(totalNumber);

            // explain 方式
            var sqlAndParams = queryable.Clone().ToSql();
            // postgreSQL: table1 真实总条目数: 99000001
            //  Index Scan Backward using table1_pkey on table1  (cost=0.57..3546021.73 rows=98993838 width=28)
            //var explain = db.Ado.SqlQuerySingle<string>("EXPLAIN " + sqlAndParams.Key, sqlAndParams.Value);

            // mysql: table1 真实总条目数: 99000099
            // mysqlRows: 44809837
            var explain = db.Ado.SqlQuerySingle<dynamic>("EXPLAIN " + sqlAndParams.Key, sqlAndParams.Value);
            var mysqlRows = explain.rows;

            // 数据页
            //  SELECT "id","name","email","address" FROM "table1"   WHERE ( "id" > @Idd0 )  ORDER BY "id" DESC LIMIT 10 offset 0;
            var list = queryable.ToPageList(1, 10);
            foreach (var item in list)
            {
                Trace.WriteLine($"id: {item.Idd}, name: {item.Name}");
            }
        }
DotNetNext commented 3 years ago

数据量大很少用统计COUNT直接发用 var list = queryable.ToPageList(1, 10); ,显示前100页

DotNetNext commented 3 years ago

下个版本将开发 自动分表 功能,你们分页将会很方便

h619633675 commented 3 years ago

好的,谢谢大佬,我想用 postgreSQL 主要的一个原因就是因为他的表物理分区,还有分布式的方式。 所以测试的 demo 数据量都会比较大,mysql 上操作,感觉越来越繁琐,sqlserver不适合我等咸鱼,哈哈。

DotNetNext commented 2 years ago

https://www.cnblogs.com/sunkaixuan/p/15488506.html 分表使用

DotNetNext commented 2 years ago

nuget 5.0.4.3 preview-04

h619633675 commented 2 years ago

大佬棒棒的,这分表和联表新方式确实看着很舒服,快年底了,大佬多囤阔落,多备物资哈