003. 大表数据连接查询优化 临时表

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ModelFirst
{
    class Program
    {
        static void Main(string[] args)
        {
            //创建上下文
            Model1Container dbContext = new Model1Container();

            #region 新增数据
            //创建一个用户和两个订单
            //UserInfo userInfo = new UserInfo();
            //userInfo.UserAddr = "珠海市";
            //userInfo.UserName = "老大";
            ////告诉上下文要对这个实体执行添加操作
            //dbContext.UserInfo.Add(userInfo);

            //OrderInfo orderInfo1 = new OrderInfo();
            //orderInfo1.BookAuth = "不认识";
            //orderInfo1.BookName = "谈谈那些你不认识的人";
            //dbContext.OrderInfo.Add(orderInfo1);

            //OrderInfo orderInfo2 = new OrderInfo();
            //orderInfo2.BookAuth = "亲戚";
            //orderInfo2.BookName = "谈谈你的亲戚";
            //dbContext.OrderInfo.Add(orderInfo2);

            ////第一种关联方法 将订单指定给用户实体
            //orderInfo1.UserInfo = userInfo;
            ////第二种关联方法 通过用户添加订单实体到自己的导航属性
            //userInfo.OrderInfo.Add(orderInfo2);
            #endregion

            #region 修改数据
            //UserInfo userInfoEdit = new UserInfo();
            //userInfoEdit.Id = 1;
            //userInfoEdit.UserAddr = "深圳市";
            //userInfoEdit.UserName = "老大";
            ////修改的第一种方法
            //dbContext.Entry<UserInfo>(userInfoEdit).State = System.Data.Entity.EntityState.Modified;

            ////修改的第二种方法, 指定某个字段做修改, 这里演示的是指定UserAddr字段; 在5.0之前(不含)的版本中这样添加
            ////dbContext.UserInfo.Attach(userInfoEdit);
            ////dbContext.Entry<UserInfo>(userInfoEdit).Property(u => u.UserAddr).IsModified = true;


            #endregion

            #region 两种延时加载的机制

            //第一种延迟加载, 用到的时候去查询数据, 注意, 只有在用到的时候才会去查, 并且用一次查一次, 这种机制下, 就算将数据放到缓存中都没有用, 还是会用到一次查一次
            //IQueryable<UserInfo> userInfoS = from u in dbContext.UserInfo
            //                                 where u.UserAddr.Contains("深")
            //                                 select u;
            ////只有在用到的时候才会去数据库查询数据
            //foreach (var userInfo in userInfoS)
            //{
            //    Console.WriteLine(userInfo.UserAddr+"   "+userInfo.UserName);
            //}

            ////var temp = from u in userInfoS
            ////           where u.Id > 1
            ////           select u;

            //第二种延时加载的机制
            IQueryable<UserInfo> userInfoS = from u in dbContext.UserInfo//.Include("OrderInfo")
                                             //where u.UserAddr.Contains("深")
                                             select u;

            ////假设当前用户表中有100个数据, 那么在此种嵌套循环下, 会和数据库交互101次, 所以就要使用from u in dbContext.UserInfo.Include("OrderInfo"), 表示在查询用户表的时候, 顺便把订单表查询出来, 这样的话, 就和数据库交互一次
            IQueryable<UserInfo> userInfoS1 = from u in dbContext.UserInfo.Include("OrderInfo")
                                              //where u.UserAddr.Contains("深")
                                             select u;
            foreach (var userInfo in userInfoS) //假设当前用户表中有100个数据, 那么在此种嵌套循环下, 会和数据库交互101次, 所以就要使用from u in dbContext.UserInfo.Include("OrderInfo"), 表示在查询用户表的时候, 顺便把订单表查询出来, 这样的话, 就和数据库交互一次
            {
                foreach (var orderInfo in userInfo.OrderInfo)
                {
                    Console.WriteLine(orderInfo.BookAuth+"   "+orderInfo.BookName);
                }
            }

            //查询的时候, 什么时候使用include, 什么时候不用Include
            //情景1: 用户表和订单表数据都是1亿条数据, 然后两个表进行连接查询的时候, 这个时候建议不要使用Include; 以此来解决大表的连接查询; 先对每个大表进行单独查询, 以此破解两个大表的联结查询
            //数据量小的时候, 为了减少查询数据库的次数, 建议使用Include

            //大数据表的查询优化:
            //1. 把连接查询进行分解, 然后在内存组装数据; 先把数据从用户表中查询出来, 然后把数据从订单表中查询出来, 都放入内存中, 最后用程序在内存中进行组装
            //2. 使用临时表; 常用于多表(超过2个以上)的大表进行组合查询的场景下, 注意, 当多个表连接的时候, 最好使用临时表, 临时表可以解决死锁问题;  注意临时表也会上锁, 但是临时表的锁, 只属于一个会话请求, 并且当此查询结束后, 此表即释放
            #endregion
            //把上面实体的变化保存到数据库中
            dbContext.SaveChanges();
            Console.WriteLine("保存成功");
            Console.Read();
        }
    }
}

 数据库

-- --------------------------------------------------
-- Entity Designer DDL Script for SQL Server 2005, 2008, 2012 and Azure
-- --------------------------------------------------
-- Date Created: 02/07/2017 22:52:32
-- Generated from EDMX file: C:\Users\LG\Desktop\ModelFirst\ModelFirst\Model1.edmx
-- --------------------------------------------------

SET QUOTED_IDENTIFIER OFF;
GO
USE [MyGroupDB];
GO
IF SCHEMA_ID(N'dbo') IS NULL EXECUTE(N'CREATE SCHEMA [dbo]');
GO

-- --------------------------------------------------
-- Dropping existing FOREIGN KEY constraints
-- --------------------------------------------------


-- --------------------------------------------------
-- Dropping existing tables
-- --------------------------------------------------


-- --------------------------------------------------
-- Creating all tables
-- --------------------------------------------------

-- Creating table 'UserInfo'
CREATE TABLE [dbo].[UserInfo] (
    [Id] int IDENTITY(1,1) NOT NULL,
    [UserName] nvarchar(32)  NOT NULL,
    [UserAddr] nvarchar(128)  NULL
);
GO

-- Creating table 'OrderInfo'
CREATE TABLE [dbo].[OrderInfo] (
    [Id] int IDENTITY(1,1) NOT NULL,
    [BookName] nvarchar(max)  NOT NULL,
    [BookAuth] nvarchar(max)  NOT NULL,
    [UserInfo_Id] int  NOT NULL
);
GO

-- --------------------------------------------------
-- Creating all PRIMARY KEY constraints
-- --------------------------------------------------

-- Creating primary key on [Id] in table 'UserInfo'
ALTER TABLE [dbo].[UserInfo]
ADD CONSTRAINT [PK_UserInfo]
    PRIMARY KEY CLUSTERED ([Id] ASC);
GO

-- Creating primary key on [Id] in table 'OrderInfo'
ALTER TABLE [dbo].[OrderInfo]
ADD CONSTRAINT [PK_OrderInfo]
    PRIMARY KEY CLUSTERED ([Id] ASC);
GO

-- --------------------------------------------------
-- Creating all FOREIGN KEY constraints
-- --------------------------------------------------

-- Creating foreign key on [UserInfo_Id] in table 'OrderInfo'
ALTER TABLE [dbo].[OrderInfo]
ADD CONSTRAINT [FK_R_UserInfo_OrderInfo]
    FOREIGN KEY ([UserInfo_Id])
    REFERENCES [dbo].[UserInfo]
        ([Id])
    ON DELETE NO ACTION ON UPDATE NO ACTION;
GO

-- Creating non-clustered index for FOREIGN KEY 'FK_R_UserInfo_OrderInfo'
CREATE INDEX [IX_FK_R_UserInfo_OrderInfo]
ON [dbo].[OrderInfo]
    ([UserInfo_Id]);
GO

-- --------------------------------------------------
-- Script has ended
-- --------------------------------------------------

 

posted on 2017-02-14 09:39  印子  阅读(192)  评论(0)    收藏  举报

导航