update

28810
2019-01-25 23:00:19 +08:00
parent a3a1f3e09a
commit cc407ad2b9
4 changed files with 177 additions and 0 deletions

@@ -48,6 +48,7 @@ FreeSql是一个功能强大的NETStandard库用于对象关系映射程序(O
* [日期/时间](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%e6%97%a5%e6%9c%9f)
* [其他](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0%e5%85%a8%e8%a7%88)
* [读写分离](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb)
* [性能](https://github.com/2881099/FreeSql/wiki/%e6%80%a7%e8%83%bd)
* API参考
## 使用指南

@@ -34,6 +34,7 @@
* [日期/时间](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%e6%97%a5%e6%9c%9f)
* [其他](https://github.com/2881099/FreeSql/wiki/%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0#%e8%a1%a8%e8%be%be%e5%bc%8f%e5%87%bd%e6%95%b0%e5%85%a8%e8%a7%88)
* [读写分离](https://github.com/2881099/FreeSql/wiki/%e8%af%bb%e5%86%99%e5%88%86%e7%a6%bb)
* [性能](https://github.com/2881099/FreeSql/wiki/%e6%80%a7%e8%83%bd)
* API参考
## 使用指南

40
分区分表.md Normal file

@@ -0,0 +1,40 @@
## 分区
分区就是把一个数据表的文件和索引分散存储在不同的物理文件中。把一张表的数据分成N多个区块这些区块可以在同一个磁盘上也可以在不同的磁盘上数据库不同现实方式有所不同。
与分表不同一张大表进行分区后他还是一张表不会变成二张表但是他存放数据的区块变多了。分区的概念我觉得就想突破磁盘I/O瓶颈想提高磁盘的读写能力来增加数据库的性能。
分区实现是比较简单的,建立分区表,根建平常的表没什么区别,并且对开发代码端来说是透明。
postgresql10以上的自动分区分表功能
1、首先创建主分区表:
```sql
create table fenbiao(
id int,
year varchar
) partition by list(year)
```
这里设置的是根据year列进行数据分表;创建后使用navicat是看不到的;
2.创建分表:
```sql
create table fenbiao_2017 partition of fenbiao for values in ('2017');
create table fenbiao_2018 partition of fenbiao for values in ('2018');
```
这样这两天数据会依靠规则插入到不同分表中,如果插入一条不符合规则的数据,则会报错误:no partition of relation "fenbiao" found for row.
## 分表
分表从表面意思上看呢就是把一张表分成N多个小表每一个小表都是完正的一张表。分表后数据都是存放在分表里总表只是一个外壳存取数据发生在一个一个的分表里面。
分表后单表的并发能力提高了磁盘I/O性能也提高了。并发能力为什么提高了呢因为查寻一次所花的时间变短了如果出现高并发的话总表可以根据不同 的查询,将并发压力分到不同的小表里面。
## 分库分表
分库分表把原本存储于一个库的数据分块存储到多个库上,把原本存储于一个表的数据分块存储到多个表上。
数据库中的数据量不一定是可控的在未进行分库分表的情况下随着时间和业务的发展库中的表会越来越多表中的数据量也会越来越大相应地数据操作增删改查的开销也会越来越大另外一台服务器的资源CPU、磁盘、内存、IO等是有限的最终数据库所能承载的数据量、数据处理能力都将遭遇瓶颈。

135
性能.md Normal file

@@ -0,0 +1,135 @@
FreeSql现实了强大的功能的同时性能并没有受影响使用反射或耗时的操作都做了缓存处理。读取数据部分采用了ExpressionTree使得FreeSql解析实体数据的速度与Dapper非常接近。
## 查询性能测试结果
```csharp
IFreeSql mysql = new FreeSql.FreeSqlBuilder()
.UseConnectionString(FreeSql.DataType.MySql, "Data Source=127.0.0.1;Port=3306;User ID=root;Password=root;Initial Catalog=cccddd;Charset=utf8;SslMode=none;Max pool size=100")
.UseLogger(new LoggerFactory().CreateLogger("FreeSql.MySql"))
//由于null会默认输出日志到控制台影响测试结果。这里传入一个空的日志输出对象
.UseAutoSyncStructure(false)
//关闭自动迁移功能
.Build();
class Song {
public int Id { get; set; }
public string Title { get; set; }
public string Url { get; set; }
public DateTime Create_time { get; set; }
public bool Is_deleted { get; set; }
}
```
测试方法忽略第一次执行结果,以第二次执行结果为准。
| | 数量 | Dapper | FreeSql | |
| - | - | - | - | - |
| [执行SQL返回实体列表](#%e6%89%a7%e8%a1%8cSQL%e8%bf%94%e5%9b%9e%e5%ae%9e%e4%bd%93%e5%88%97%e8%a1%a8) | 131072 | 00:00:00.6234959 | 00:00:00.6470552 | |
| [执行SQL返回元组列表](#%e6%89%a7%e8%a1%8cSQL%e8%bf%94%e5%9b%9e%e5%85%83%e7%bb%84%e5%88%97%e8%a1%a8) | 131072 | 00:00:00.4242411 | 00:00:00.5773532 | |
| [执行SQL返回dynamic列表](#%e6%89%a7%e8%a1%8cSQL%e8%bf%94%e5%9b%9edynamic%e5%88%97%e8%a1%a8) | 131072 | 00:00:00.6448897 | 00:00:00.9447454 | (不推使用) |
| [Dapper.Query VS FreeSql.ToList](Dapper.Query+VS+FreeSql.ToList) | 131072 | 00:00:00.6001112 | 00:00:00.6228980 | (使用频率最高)
好吧FreeSql认输你可能有疑问为什么比Dapper慢总能看到某某orm宣称性能超过Dapper多少都是Emit或ExpressionTree再比已经没有意义。
FreeSql支持更复杂的数据库类型解析有一些类型需要递归或循环才能解析到正确的值如果还说比Dapper快那是在欺骗自己和世界。
目前的性能可以说相差无及,并且真实项目的性能损耗更多不在这个环节,应该用更优的设计来提升性能。
> 由于Dapper没有批量插入/更新/删除的功能并且都是执行一条SQL命令测试结果没有意义。
> FreeSql批量插入使用的命令INSERT INTO Song (...) VALUES(...),VALUES(...),VALUES(...)...
### 执行SQL返回实体列表
```csharp
[Fact]
public void QueryEntity() {
var sb = new StringBuilder();
var time = new Stopwatch();
time.Restart();
List<Song> dplist1 = null;
using (var conn = g.mysql.Ado.MasterPool.Get()) {
dplist1 = Dapper.SqlMapper.Query<Song>(conn.Value, "select * from song").ToList();
}
time.Stop();
sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {dplist1.Count}; ORM: Dapper");
time.Restart();
var t3 = g.mysql.Ado.Query<Song>("select * from song");
time.Stop();
sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {t3.Count}; ORM: FreeSql*");
}
```
### 执行SQL返回元组列表
```csharp
[Fact]
public void QueryTuple() {
var sb = new StringBuilder();
var time = new Stopwatch();
time.Restart();
List<(int, string, string)> dplist2 = null;
using (var conn = g.mysql.Ado.MasterPool.Get()) {
dplist2 = Dapper.SqlMapper.Query<(int, string, string)>(conn.Value, "select * from song").ToList();
}
time.Stop();
sb.AppendLine($"Elapsed: {time.Elapsed}; Query Tuple Counts: {dplist2.Count}; ORM: Dapper");
time.Restart();
var t4 = g.mysql.Ado.Query<(int, string, string)>("select * from song");
time.Stop();
sb.AppendLine($"Elapsed: {time.Elapsed}; Query Tuple Counts: {t4.Count}; ORM: FreeSql*");
}
```
### 执行SQL返回dynamic列表
```csharp
[Fact]
public void Query() {
var sb = new StringBuilder();
var time = new Stopwatch();
time.Restart();
List<dynamic> dplist3 = null;
using (var conn = g.mysql.Ado.MasterPool.Get()) {
dplist3 = Dapper.SqlMapper.Query<dynamic>(conn.Value, "select * from song").ToList();
}
time.Stop();
sb.AppendLine($"Elapsed: {time.Elapsed}; Query Dynamic Counts: {dplist3.Count}; ORM: Dapper");
time.Restart();
var t5 = g.mysql.Ado.Query<dynamic>("select * from song");
time.Stop();
sb.AppendLine($"Elapsed: {time.Elapsed}; Query Dynamic Counts: {t3.Count}; ORM: FreeSql*");
}
```
### Dapper.Query VS FreeSql.ToList
```csharp
[Fact]
public void Query() {
var sb = new StringBuilder();
var time = new Stopwatch();
time.Restart();
var t3 = g.mysql.Select<Song>().ToList();
time.Stop();
sb.AppendLine($"Elapsed: {time.Elapsed}; ToList Entity Counts: {t3.Count}; ORM: FreeSql*");
time.Restart();
List<Song> dplist1 = null;
using (var conn = g.mysql.Ado.MasterPool.Get()) {
dplist1 = Dapper.SqlMapper.Query<Song>(conn.Value, "select * from song").ToList();
}
time.Stop();
sb.AppendLine($"Elapsed: {time.Elapsed}; Query Entity Counts: {dplist1.Count}; ORM: Dapper");
}
```
> 更多测试源码FreeSql/FreeSql.Tests.PerformanceTests/MySqlAdoTest.cs