日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無(wú)先后,達(dá)者為師

網(wǎng)站首頁(yè) 編程語(yǔ)言 正文

EF?Core通過(guò)顯式編譯提高查詢性能_實(shí)用技巧

作者:Sweet-Tang ? 更新時(shí)間: 2022-04-26 編程語(yǔ)言

今天,我將向您展示這些EF Core中一個(gè)很酷的功能,通過(guò)使用顯式編譯的查詢,提高查詢性能。

不過(guò)在介紹具體內(nèi)容之前,需要說(shuō)明一點(diǎn),EF Core已經(jīng)對(duì)表達(dá)式的編譯使用了緩存;當(dāng)您的代碼需要重用以前執(zhí)行的查詢時(shí),EF Core將使用哈希查找并從緩存中返回已編譯的查詢。

不過(guò),您可能希望直接對(duì)查詢進(jìn)行編譯,跳過(guò)哈希的計(jì)算和緩存查找。我們可以通過(guò)在EF靜態(tài)類(lèi)中下面兩個(gè)方法來(lái)實(shí)現(xiàn):

  • EF.CompileQuery()
  • EF.CompileAsyncQuery()

這些方法允許您定義一個(gè)已編譯的查詢,然后通過(guò)調(diào)用一個(gè)委托調(diào)用它。

為了避免因?yàn)閿?shù)據(jù)庫(kù)查詢產(chǎn)生測(cè)試結(jié)果的差異,我們這里使用內(nèi)存數(shù)據(jù)庫(kù),它開(kāi)銷(xiāo)更小,同時(shí)也可以避免數(shù)據(jù)庫(kù)優(yōu)化執(zhí)行計(jì)劃以及緩存所帶來(lái)的問(wèn)題。

實(shí)體定義以前數(shù)據(jù)庫(kù)DbContext

定義實(shí)體

在這我們定義一個(gè)Category實(shí)體類(lèi)型,非常簡(jiǎn)單,只有兩個(gè)屬性。

    public class Category
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
    }

數(shù)據(jù)庫(kù)DbContext

FillCategories方法中,將內(nèi)存數(shù)據(jù)庫(kù)中增加三條記錄。

    public class TestDbContext : DbContext
    {
        public TestDbContext(DbContextOptions options) : base(options)
        {
        }

        public DbSet Categories { get; set; }

        public void FillCategories()
        {
            var foodCategory = new Category {
                Id = Guid.NewGuid(),
                Name = "Food"
            };

            Categories.AddRange(foodCategory, new Category {
                Id = Guid.NewGuid(),
                Name = "Drinks"
            }, new Category {
                Id = Guid.NewGuid(),
                Name = "Clothing"
            }, new Category {
                Id = Guid.NewGuid(),
                Name = "Electronis"
            });


            SaveChanges(true);
        }
    }

測(cè)試代碼

    public class CompileQueryTest
    {
        private   Func _getCategory =
            EF.CompileQuery((TestDbContext context, Guid id) => context.Categories.FirstOrDefault(c => c.Id == id));

        private readonly TestDbContext _dbContext;

        public CompileQueryTest()
        {
            var options = new DbContextOptionsBuilder().UseInMemoryDatabase(Guid.NewGuid().ToString()).Options;
            var context = new TestDbContext(options);

            context.FillCategories();

            _dbContext = context;
        }

        private readonly Guid _queryId = Guid.NewGuid();

        [Benchmark]
        public void CompiledQuery()
        {
            _ = _getCategory(_dbContext, _queryId);
        }


        [Benchmark]
        public void UnCompiledQuery()
        {

            _ = _dbContext.Categories.FirstOrDefault(c => c.Id == _queryId);

        }
    }

為了更加接近測(cè)試結(jié)果,我們?cè)跇?gòu)造函數(shù)中創(chuàng)建TestDbContext對(duì)象以及填充數(shù)據(jù)庫(kù)。

測(cè)試結(jié)果

我們使用Benchmark.Net進(jìn)行基準(zhǔn)測(cè)試,測(cè)試結(jié)果如下:

Method Mean Error StdDev
CompiledQuery 10.59 us 0.0580 us 0.0543 us
UnCompiledQuery 79.55 us 0.7860 us 0.7353 us

經(jīng)過(guò)編譯的查詢比未編譯過(guò)的查詢存在接近8倍的差距。如果您對(duì)這個(gè)功能感興趣,不防自己測(cè)試一下。

原文鏈接:https://www.cnblogs.com/tdfblog/p/ef-core-compilequery.html

欄目分類(lèi)
最近更新