如何应付表数据过大的查询问题?(如何尽量避免大表关联)

原文:如何应付表数据过大的查询问题?(如何尽量避免大表关联)

一般来说,对于做B/S架构的朋友来说,更有机会遇到高并发的数据库访问情况,因为现在WEB的普及速度就像火箭升空,同时就会因为高访问量带来一系列性能问题,而数据库一直是用户与商人之间交流的重要平台.用户是没有耐心忍受一个查询需要用上10秒以上的,或者更少些,如果经常出现服务器死机或者是报查询超时,我想那将是失败的项目。做了几年的WEB工作,不才,一直没有遇到过大访问量或者是海量数据的情况.这里并不是说没有海量数据的项目就不是好项目,要看项目的应用场合.

最近做项目时,偶然得到了这个机会,在我工作过程中,本人发现的单表最大记录数高达9位数.像订单表什么的也有8位数.在查询订单的时候往往不能通过单表查询就能解决,还要和其它相关表进行关联查询.如此关联的表数据不大还好,一旦发生大表关联大表,在查询时就有可能出现慢长的等待。

主旨: 如何避免这种情况的发生呢?既然有了这样的数据,需求还是要实现,这里就我最近针对数据库的优化过程,我分两篇文章来说明下.

第一篇:如何尽量避免大表关联.

第二篇:对大表进行分区.

背景:有两张表:

1:订单表:记录用户订单的详细信息.order,其中有一个会员卡号字段cardNo,订单产生时间.

2:会员表:记录会员相关信息.member,一个会员有一个代理号:proxyID,代理下面有许多的会员卡:cardNo,它们共用一个代理号.

两表通过cardNo来相关联.

需求:查询一个用户或者某些用户某一时间段所有会员卡产生的订单情况.

实现SQL:

select 字段 from order

inner join member on

order.cardNo=member.cardNo

and member.proxyID in(‘a-01‘,代理号二)

and 时间 between ‘20080101‘ and ‘20080131‘

本人见解:我想一般的朋友看到这样的需求大多会写出这样的查询SQL,如果不喜欢用in或者认为in的性能不好的朋友可用union all 代替.SQL语句可以说简单的不能再简单了,本身并无问题,只是如果两表的数据都在百万以上,而且字段都特别多.此时如果只有索引的帮忙下并不一定能达到预期的效果.

解决方案一:利用表变量来替换大表关联,表变量的作用域为一个批处理,批处理完了,表变量也会随之失效,比起临时表有它独特的优点:不用手动去删除表变量以释放内存。

可行性:因为需求中的输出字段大多来自订单表,member表只起到数据约束的作用,和查询用户会员卡号的作用,所有可以先把代理的会员卡号先取到表变量中,然后利用带有卡号的表变量和订单表相关联查询.

declare @t table

(cardNo int)

insert @t

select cardNo from member where in(‘a-01‘,代理号二)

select 字段 from order

inner join @t on

[email protected] and 时间 between ‘20080101‘ and ‘20080131‘

这里我就不贴性能比较图了,有兴趣的朋友可以自己尝试下.这种方法在查询人员比较多的时候特别有帮助.它要开发员根据实际情况详细比较,结果并不是统一的,不同的环境结果可能不一样.希望大家理解.

解决方案二:利用索引视图来提高大表关联的性能.

可行性:一般在大表关联时,我们的输出列都远小于两表的字段合,像上面的member表只用到了其中的两个字段(cardNo,proxyID).设想一下,此时的member表如果只有这两个字段情况会不会好些呢?答案不言而喻.

视图这个名词在我以前对它的印象中,从来没有认为视图能优化查询,因为我认为视图对于数据库来说就是一个虚假表,在数据库中并无实际物理位置来存储数据.对于用户来说无非就是通过不同的视角来观看结果.视图数据

的产生都是实时的,即当调用视图时,自动扩展视图,去运行里面相应的select语句.后来才知道在2000后的版本中视图分一般视图和索引视图,一般视图就是没有创建索引的我印象中的视图.而创建了视图后就称为索引视图.索引视图是物理存在的,可在视图上首先创建一个唯一的聚集索引,其它字段上也可创建非聚集索引.在不改变基础表的情况下,起到了优化的效果.

CREATE VIEW memberView

WITH SCHEMABINDING

AS

SELECT cardNo,proxyID from member

GO

--以会员卡号创建一个唯一聚集索引

CREATE UNIQUE CLUSTERED INDEX ix_member_cardNo

ON member (cardNo);

GO

注意:创建索引视图要点:

1: CREATE VIEW memberView后面要跟上WITH SCHEMABINDING

理由:• 使用 schemaname.objectname 明确识别视图所引用的所有对象,而不管是哪个用户访问该视图。

• 不会以导致视图定义非法或强制 SQL Server 在该视图上重新创建索引的方式,更改视图定义中所引用的对象。

2:视图上的第一个索引必须为 CLUSTERED 和 UNIQUE。

理由:必须为 UNIQUE 以便在维护索引视图期间,轻松地按键值查找视图中的记录,并阻止创建带有重复项目的视图(要求维护特殊的逻辑)。必须为 CLUSTERED,因为只有聚集索引才能在强制唯一性的同时存储行。

3:以下情况可考虑创建索引视图:

• 可预先计算聚合并将其保存在索引中,从而在查询执行时,最小化高成本的计算。

• 可预先联接各个表并保存最终获得的数据集。

• 可保存联接或聚合的组合。

4:基础表的更新会引发索引视力的更新。

5:索引视图的创建同时会带来维护上的开销。

理由:1:因为索引视图是物理存在的。

2:要额外的维护索引.

实现:SQL:select 字段 from order

inner join memberView on

order.cardNo=member.cardNo

and member.proxyID=in(‘a-01‘,代理号二)

and 时间 between ‘20080101‘ and ‘20080131‘

总结:两种解决方案来看,各有所长,一般可以优先考虑使用索引视图来优化大表关联。以上是本人对于如何尽量避免发生大表关联所采取的措施,望大家指教。

注:

   本文参考:http://www.51cto.com/html/2005/1115/11396.htm

时间: 2024-11-09 18:04:32

如何应付表数据过大的查询问题?(如何尽量避免大表关联)的相关文章

SQL Server 的表数据简单操作(表数据查询)

--表数据查询----数据的基本查询-- --数据简单的查询--select * | 字段名[,字段名2, ...] from 数据表名 [where 条件表达式] 例:use 商品管理数据库goselect * from 商品信息表select 商品编号,商品名称,产地 from 商品信息表selelct * from 商品信息表 where 产地='辽宁沈阳' --关键字辅助查询----1)distinct关键字 (用来消除查询结果中的重复行,使用时紧跟在select命令后)--select

应用子表时如何将开窗查询事件做成多选?

应用子表开窗事件选择的时候,如何将开窗查询事件做成多选? 其实,做一些改造就能达到效果哦 修改SheetTextBox.js的 ListMasterCallBack 函数,将设置控件的值逻辑改为以下方式 检测某个主键字段,是否已经在子表数据存在,如果不存在,则调用子表的新增行方法,将开窗选中行的数据写入新增的子表行中:如果检测某个主键字段值已经在子表中存在,则更新这一行数据: ListMasterCallBack 去除自动关闭窗体代码以便仍然可以继续双击:

oracle-复制表结构和表数据

1.复制表结构和表数据 create table table_new as select * from table_old 2.复制表结构 create table table_new as select * from table_old where 1<>1 3.复制表的指定字段 create table table_new as select o.column1,o.column2 from table_old o where 1<>1 4.复制表的指定字段的数据 create

PL/SQL Developer中表结构、表数据的导出和导入

导出表结构: Tools(工具)-->Export User Objects(导出用户对象) -->选择要导出的表(包括Sequence等)-->.sql文件,导出的都为sql文件 导出表数据: Tools(工具)-->Export Tables(导出表)-->选择表,选择SQL Inserts(SQL 插入)-->.sql文件 导入表结构: 执行刚刚导出的sql文件,记住要删掉table前的用户名,比如以前这表名为sys.tablename,必须删除sys 导入表数据

海量数据查询关系型数据库存储大数据,要点就是:简单存储、分区分表、高效索引、批量写入

海量数据查询 https://www.cnblogs.com/nnhy/p/DbForBigData.html 相当一部分大数据分析处理的原始数据来自关系型数据库,处理结果也存放在关系型数据库中.原因在于超过99%的软件系统采用传统的关系型数据库,大家对它们很熟悉,用起来得心应手. 在我们正式的大数据团队,数仓(数据仓库Hive+HBase)的数据收集同样来自Oracle或MySql,处理后的统计结果和明细,尽管保存在Hive中,但也会定时推送到Oracle/MySql,供前台系统读取展示,生成

大数据技术之_29_MySQL 高級面试重点串讲_02_Mysql 简介+Linux 版的安装+逻辑架构介绍+性能优化+性能分析+查询截取分析+分区分库分表简介+锁机制+主从复制

第1章 Mysql 简介1.1 概述1.2 高级 MySQL第2章 Mysql Linux 版的安装2.1 下载地址2.2 检查当前系统是否安装过 mysql2.3 修改 Mysql 配置文件位置2.4 修改字符集和数据存储路径2.5 MySQL 的安装位置说明2.6 Mysql 配置文件说明2.7 Mysql 的数据存放目录第3章 Mysql 逻辑架构介绍3.1 总体概览3.2 查询说明第4章 Mysql 性能优化4.1 影响 mysql 的性能因素4.2 查询与索引优化分析4.2.1 性能下

多表数据记录查询

1.关系数据的各种操作 并(union) 把相同字段数目和字段类型的表合并到一起 笛卡尔积(cartesian product) 内连接 inner jion 所谓连接就是在表关系的笛卡尔积数据记录中,按照相应字段值的比较条件进行选择生成一个新的关系.连接又分为内连接,外连接,交叉连接. 内连接:在表关系的笛卡尔积数据记录中,保留表关系中所有匹配的数据记录,舍弃不匹配的数据记录. 按照匹配的条件可以分成自然连接,等值连接,和不等连接 自然连接: 表关系的笛卡尔积中,首先根据表关系中相同名称的字段

PLSQL_Oracle外部表的概念和使用(案例)(通过外部表直接查询数据文件以节数据库表空间)

2014-08-25 BaoXinjian 一.摘要 ORACLE外部表用来存取数据库以外的文本文件(Text File)或ORACLE专属格式文件. 因此,建立外部表时不会产生段.区.数据块等存储结构,只有与表相关的定义放在数据字典中. 外部表,顾名思义,存储在数据库外面的表. 当存取时才能从ORACLE专属格式文件中取得数据,外部表仅供查询,不能对外部表的内容进行修改(INSERT.UPDATE.DELETE操作). 不能对外部表建立索引.因为创建索引就意味着要存在对应的索引记录.而外部表其

大数据江湖之即席查询与分析(下篇)--手把手教你搭建即席查询与分析Demo

上篇小弟分享了几个"即席查询与分析"的典型案例,引起了不少共鸣,好多小伙伴迫不及待地追问我们:说好的"手把手教你搭建即席查询与分析Demo"啥时候能出?说到就得做到,差啥不能差人品,本篇只分享技术干货,目的只有一个,就是让每一个伙伴都能根据本篇向导搭建出一个"即席查询与分析Demo". 为了让各位伙伴能够尽快上手体验,所选案例就以上一篇中的"机动车缉查布控即席查询与分析"为例,上篇我们已经比较详尽的分析了用户需求,没好好听课的