两个sql设计方案的比较
我有一个买方表Buyer,大概1万条记录;一个卖方表Sale,大概5万条记录。有一些买方和卖方之间是有某种关联的,这种关联关系被记录在Partner表里,Partner表中的关键字段包括BuyerID,SaleID和LinkManID,其中LinkManID是卖方的业务员之一。系统里还有一个联系人的概念,对于每一个买方,如果它和卖方在Partner表里有记录,就取Partner表中的LinkManID作为联系人ID;如果它和卖方在Partner表中无记录,那么需要去查找这个卖方的主业务员ID(每个卖方有1至n个业务员,其中有且仅有一个主业务员)来作为联系人ID。
在程序中,经常涉及到查询和某买方有业务关系的卖方列表,里面都需要显示联系人信息。现在有两个方案:
(1)生成一个视图,视图里就三列:BuyerID,SaleID和LinkManID。视图很容易写,形成的视图在程序里用起来也很方便。但如果不加上查询条件,直接查询这个视图,会查出5五*1万=5亿条记录(卖方和买方表作笛卡尔积)。虽然我们实际用的时候,肯定会加上查询条件(不加查询条件是没有意义的),但似乎也存在忘加查询条件把服务器搞死的可能;另外,一个视图,只有给它加上查询条件才能使用,是不是也有点怪怪的?毕竟sqlserver不支持所谓带参视图。
(2)写一个函数,传入BuyerID和SaleID,以LinkManID为返回值。函数虽然好写,但放在查询语句里很别扭,用起来非常不舒服。
下面给出两个方案的伪代码:

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

在一开始,我个人比较偏向于方案1,因为正如伪代码中所显示的那样,使用视图更容易写查询语句,也更容易和其他的表进行关联;另外,从运行效率上,我对函数的运行效率深表怀疑,认为用视图更快。结果,当我试着在项目里把两种方案都试验了之后,吃了一惊,函数法的速度远远高于视图法。这时候我还不服气,忙着去给视图加索引,这时候才惊觉,由于我这个视图是使用外连接得到的(买方表和卖方表笛卡尔积),所以根本无法建立索引(如果这一点说错了请大家指正,在我建立索引的时候报错“无法在视图上创建 索引,因为该视图未绑定到架构”,百度了一下,发现视图中有外连接的话是不能建立索引的)。由于对视图的查询很慢,在sql server的查询计划里我们甚至可以看到它对要和视图进行连接的[user]表进行了lasy spool,而这个步骤又占去了查询的绝大多数时间:
而另一个让我以前没有想到的是,使用函数的效率竟然很高,下面是方案2的执行计划中标量计算所占的cpu百分比:
所以,最后自己还是采用了方案2,虽然用起来多了一层嵌套,但无论是安全性还是效率,都好于1。
两个sql设计方案的比较的更多相关文章
- 处于同一个域中的两台Sql server 实例无法连接
处于同一个域中的两台Sql server 实例无法连接,报的错误信息如下: A network-related or instance-specific error occurred while es ...
- 处于同一域中的两台SQL Server 实例无法连接
处于同一个域中的两台Sql server 实例无法连接,报的错误信息如下: A network-related or instance-specific error occurred while es ...
- 两道sql面试题
两道sql面试题: 1. 数据库表A的数据如下: year quarter 2001 1 2001 ...
- 两个SQL查询,横向合并为一个查询结果
第一条sql: select unit,count(*)as number from archives_management group by unit 第二条sql: select fine_uni ...
- spring boot集成mybatis只剩两个sql 并提示 Cannot obtain primary key information from the database, generated objects may be incomplete
前言 spring boot集成mybatis时只生成两个sql, 搞了一个早上,终于找到原因了 找了很多办法都没有解决, 最后注意到生成sql的时候打印了一句话: Cannot obtain pri ...
- 两台SQL Server数据同步解决方案
复制的概念 复制是将一组数据从一个数据源拷贝到多个数据源的技术,是将一份数据发布到多个存储站点上的有效方式.使用复制技术,用户可以将一份数据发布到多台服务器上,从而使不同的服务器用户都可以在权限的许可 ...
- (转载)按行合并两个sql的查询结果
(转载)http://blog.csdn.net/wxwstrue/article/details/6784774 Union all join 是平行合并 为水平连接 Union all 是垂直合并 ...
- CASE WHEN 及 SELECT CASE WHEN的用法(写了一坨烂代码发现两条sql就行了, 哎)
转自:http://blog.sina.com.cn/s/blog_4c538f6c01012mzt.html Case具有两种格式.简单Case函数和Case搜索函数. 简单Case函数 CASE ...
- 比较两个Sql数据库是否相同
1.打开VS20122.SQL→架构比较→新建架构比较3.在源和目标上分别填上两个待比较的数据库的信息4.点击比较,不一会儿,系统就会列出两个数据库的差异了.
随机推荐
- (转载)MYSQL千万级数据量的优化方法积累
转载自:http://blog.sina.com.cn/s/blog_85ead02a0101csci.html MYSQL千万级数据量的优化方法积累 1.分库分表 很明显,一个主表(也就是很重要的表 ...
- 基于C#的PISDK研究(理论)
本篇文章主要对PISDK体系结构以及重点类进行阐述. 当我们决定使用PISDK时,可能会使用到下面的类库: 在上表中,PISDK.dll为核心类,大部分主要功能都在该类中.PISDKCommon.dl ...
- CSS设计指南之伪类
伪类这个叫法源自它们与类相似,但实际上并没有类会附加到标记中的标签上.伪类分两种. UI伪类会在HTML元素处于某个状态时(比如鼠标指针位于链接上),为该元素应用CSS样式. 结构化伪类会在标记中存在 ...
- WebSocket简单介绍(1)
HTML5作为下一代WEB标准,拥有许多引人注目的新特性,如Canvas.本地存储.多媒体编程接口.WebSocket等等.今天我们就来看看具有“Web TCP”之称的WebSocket. WebSo ...
- Sublime Text 2.0.2 注册码激活
直接输入注册码就可以了 ----- BEGIN LICENSE ----- Andrew Weber Single User License EA7E-855605 813A03DD 5E4AD9E6 ...
- POJ——2449 Remmarguts' Date
Description "Good man never makes girls wait or breaks an appointment!" said the mandarin ...
- [NOIP2017]列队 线段树
---题面--- 题解: 之前写的splay,,,然而一直没调出来,我感觉是某个细节想错了,,然而已经重构4次代码不想再写splay了.于是今天尝试了线段树的解法. 首先因为每次出列之后的变化都是将当 ...
- BZOJ5323 [Jxoi2018]游戏 【数论/数学】
题目链接 BZOJ5323 题解 有一些数是不能被别的数筛掉的 这些数出现最晚的位置就是该排列的\(t(p)\) 所以我们只需找出所有这些数,线性筛一下即可,设有\(m\)个 然后枚举最后的位置 \[ ...
- NOI2018 D1T1 [NOI2018]归程 解题报告
P4768 [NOI2018]归程 题目描述 本题的故事发生在魔力之都,在这里我们将为你介绍一些必要的设定. 魔力之都可以抽象成一个 \(n\) 个节点.\(m\) 条边的无向连通图(节点的编号从 \ ...
- [Usaco2005 Dec]Cleaning Shifts 清理牛棚 (DP优化/线段树)
[Usaco2005 Dec] Cleaning Shifts 清理牛棚 题目描述 Farmer John's cows, pampered since birth, have reached new ...