======== 以下方法哪个性能更加好 ==========

愚者只看星不看答案 2019-05-23 03:12:28
尽量实现单表查询,而避免使用 join,特别是在join的表的记录数非常多的情况下,是我主观认为的一个最佳实践

以下举例认为 Books和Authors两个表各有500万条记录,要求一次性查询出 Books的所有记录,并查询出 Books.AuthorID 关连的 Author.AuthorName

Books.AuthorID 是 Authors.AuthorID 的外键



以下是三种方法

方法一,个人认为性能最差

select b.*,a.* from Books b inner join Authors a on b.AuthorID=a.AuthorID


方法二,先过滤一部分 Author 的子集,然后在表变量join,个人认为性能比方法一好

create proc usp_Books_GetBooks
as
begin
DECLARE @t_Books table
(
BookId int,
BookName nvarchar(50),
UnitPrice bigint,
AuthorID int
);
insert into @t_Books select b.BookID,b.BookName,b.UnitPrice,b.AuthorID from Books b;

DECLARE @t_Authors table
(
AuthorID int,
AuthorName nvarchar(50)
);
insert into @t_Authors select a.AuthorID,a.AuthorName from Authors a where a.AuthorID in(select t_Books.AuthorID from @t_Books t_Books);

select t_Books.*,t_Authors.* from @t_Books t_Books inner join @t_Authors t_Authors on t_Authors.AuthorID=t_Books.AuthorID;
end


方法三,不做join,生成两个结果集,让开发人员在编程语言中实现(只考虑性能,不告诉开发人员是否方便)

create proc usp_Books_GetBooks_1
as
begin

DECLARE @t_Books table
(
BookId int,
BookName nvarchar(50),
UnitPrice bigint,
AuthorID int
);
insert into @t_Books select b.BookID,b.BookName,b.UnitPrice,b.AuthorID from Books b;

select a.AuthorID,a.AuthorName from Authors a where a.AuthorID in(select t_Books.AuthorID from @t_Books t_Books);
select * from @t_Books;

end


大家对方法二,三有什么看法,认为哪种比较好? 多谢

...全文
113 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
吉普赛的歌 版主 2019-05-23
  • 打赏
  • 举报
回复
你犯了两个错误。 一是认为 join 比其它方式慢; 二是没有结合实际的查询。 SQL 本来就是集合操作, join 是一个非常常见的操作, 单纯的连接,SQL Server 绝对不会你手工处理的效率低。 另外, 两个 500 万的大表连接, 如同把全中国的人数一遍一样, 没什么优化可言。 ——所谓SQL优化, 从来都只是百里挑一,能万里挑一是更好。全部显示出来,一般情况没意义,纯粹在拼硬件,不具现实价值。 你应该把你常见的完整查询语句贴出来( 一般会有筛选、分页、排序等等 ), 再来和大家讨论。
听雨停了 2019-05-23
  • 打赏
  • 举报
回复
个人也比较支持第一种方法,数据库搞数据本来就是它的强项。至于你说的第二种方案,我觉得有点多此一举啦。而且第二个查询你还用了一个in的子查询,那就更慢了。第三种方案,把两个表的数据都加载到内存中让程序去处理,个人感觉就更有点扯了。你把两个表的数据单独查询出来的时间,估计join可能已经都结束了。纯属个人见解
  • 打赏
  • 举报
回复
引用 1 楼 雨夹雪 的回复:
第一个最好,表变量不适合大表,其他不说了
不对吧,第一个性能应该也是比较差的,第二个表变量将大数据量读到内存,的确也是劣势。
雨夹雪 2019-05-23
  • 打赏
  • 举报
回复
第一个最好,表变量不适合大表,其他不说了
notepad--v3.4 windows Notepad--v3.4.0-plugin-Installer.exe 是win10下面的插件版安装包,会关联右键菜单等。 Notepad--v3.4.0-win10-portable.zip 是绿色免安装版本,解压即用,不会关联右键菜单注册表。 Ndd-quick-v3.3.0-win10-single-portable.zip 是单文件绿色免安装版,只包含皮肤和vc依赖库,不含插件、不含文件对比,主推轻量级、快速反应。适合只需要纯粹、轻快级,文本编辑器的用户。不定期发布。 MacOS 版本 Notepad--v3.4.0-mac_x64_12.3.dmg 是macos 12.x 及以后的版本。 Notepad--v3.4.0-mac_arm64_12.3.dmg 是macos 12.x 及以后 arm64 m1/m2芯片 的版本。第一次安装时,需要在设置偏好里面,放开苹果的安装限制,才能正常识别,请自行放开设置一下。 如果还是有问题,参考帖子:#I8JTJN:macOS Sonoma 14.1.1安装提示已损坏:macOS Sonoma 14.1.1安装提示已损坏 uos com.hmja.notepad_3.4.0.0_amd64.deb 是x64 cpu架构的uos系统对应的ndd版本。 其余系统版本后续会发布。 3.4 修改如下: 1 支持文件标签拖入拖出到新窗口的效果。 2 windows下修改快捷键放开。 3 按行号切分大文件。 4 大文件打开时,在文件夹查找所在目录,macos下可能会崩溃问题。 5 目录右键增加删除文件、文件夹功能。 6 补充深色主题下rust语法高亮; lisp 语法失效问题。 7 linux下信号打开文件,不拿锁,打开文件在消息队列中去做。

34,838

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧