首页 > 如何应付表数据过大的查询问题?(如何尽量避免大表关联)[转]

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

  一般来说,对于做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'

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

更多相关:

  • 大多数Ios开发者都喜欢运用xib以及约束来布局,这样省去了大量初始化代码,但是xib的使用也是存在不少差异的:一.xib的几个重要属性xib的文件名File's ownerxib中的视图classxib文件中的视图Outlet指向二.Demo实现1.加载xib中File's owner为nil的视图blueView.pngViewC...

  • # 视图高级笔记:### `add_url_rule(rule,endpoint=None,view_func=None)`这个方法用来添加url与视图函数的映射。如果没有填写`endpoint`,那么默认会使用`view_func`的名字作为`endpoint`。以后在使用`url_for`的时候,就要看在映射的时候有没有传递`en...

  • UIView 1.为什么要UIView .可以用UIView作为容器,存放子视图 .管理事件UIEvent   2.ios坐标系 以左上角为坐标原点,向右边是x的正方向,向下是y的正向方 bounds: 相对于视图本身而言(0,0,w, h) frame:相对于父视图的坐标 center: 相对于父视图的中心点坐标   3.将一...

  • 最近项目中发现一怪问题,使用DB项目发布数据库时,总提示 “(110,1): SQL72014: .Net SqlClient Data Provider: Msg 1222, Level 16, State 56, Procedure sp_refreshsqlmodule_internal, Line 67 Lock reques...

  • 转载地址:http://www.2cto.com/database/201212/176775.html 一、视图的基本介绍  www.2cto.com   视图是虚拟的表。与包含数据的表不一样,视图只包含使用时动态检索数据的查询。 使用视图需要MySQL5及以后的版本支持。 下面是视图的一些常见应用: 重用SQL语句; 简化复杂的S...

  • 一、视图(Views)与 同义词   1、视图:实际上是对查询结果集的封装,视图本身不存储任何数据,所有的数据都存放在原来的表中;      在逻辑上可以把视图看作是一张表   2、作用: 封装查询语句,简化复杂的查询需求屏蔽表中的细节  3、语法:  create [or replace] view 视图的名称 as 查询语句...

  • explain显示了mysql如何使用索引来处理select语句以及连接表。可以帮助选择更好的索引和写出更优化的查询语句。 虽然这篇文章我写的很长,但看起来真的不会困啊,真的都是干货啊!!!! 先解析一条sql语句,看出现什么内容 EXPLAIN SELECT s.uid,s.username,s.name,f.email,f.mob...

  • 重建索引  如果表中记录频繁地被删除或插入,尽管表中的记录总量保持不变,索引空间的使用量会不断增加。虽然记录从索引中被删除,但是该记录索引项的使用空间不能被重新使用。因此,如果表变化不定,索引空间量会不断增加,不论表中记录数量是否增加,这是因为索引中无效空间会增加。 要回收那些曾被删除记录使用的空间,需要使用Alter index r...

  • 其实SQL能力很差劲,简单查询还成,复杂查询以及优化,基本脑子里没有概念。了解一下概念,然后打算找本理论书好好看看。 先到处找了些优化的sql,整理出来,记录一下。     1、对查询进行优化,应尽量避免全表扫描,首先应考虑在where 及order by 涉及的列上建立索引。     2、应尽量避免在where 子句中对字段进行n...

  • 原文地址:oracle索引的简单总结作者:kindle一、索引的概念:     数据库的索引类似于书籍的索引。在书籍中,索引允许用户不必翻阅完整个书就能迅速地找到所需要的信息。在数据库中,索引也允许数据库程序迅速地找到表中的数据,而不必扫描整个数据库。 二、索引的特点:     1.索引可以加快数据库的检索速度     2.索引降低...

  • 关注我的头条号,获取更多运维相关知识。你想了解哪方面的运维知识,请评论区告诉我,我会尽快更新~MySQL 数据库,基本上运维都会接触到,而对于数据库的性能优化,想必是大家比较关注的,下面分享一些调优技巧。先决条件安装 MySQL,版本大于 5.7有部分数据操作系统、数据库管理员权限MySQL 系统性能优化在系统层面,调整硬件和软件选项...

  • spring data jpa提供了多种查询方式,如下:方法名称查询继承Repository接口测试代码方法名称中支持的关键字(官方文档提供)使用JPA命名查询在User实体中定义jpql(类似于hql)jpql(百度百科)继承JpaRepository接口测试使用@Query查询和命名查询不同的是,将jpql写到了 dao 方法上,...

  • 转自:http://www.cnblogs.com/fish-li/archive/2011/06/06/2073626.html   对于SqlServer的优化来说,可能优化查询是很常见的事情。关于数据库的优化,本身也是一个涉及面比较的广的话题,本文只谈优化查询时如何看懂SqlServer查询计划。由于我对SqlServer的认识...

  • 一.实现基础功能之一(记账)   一个记账本最基础之一的功能就是记账,所以也是首先要解决的问题,我选择了上学期使用的MySQL数据库来对账本进行存储。   我选择记账的方法是分开记账,就是支出放在一个表,收入放在一个表,这样在数据库方面会比较的直观的看到,但是在显示的时候就会产生部美观的问题,就是支出和收入都是分开来的,没有办法按照时...

  • 在Navicat中,我们选中一个表,双击打开,这是如果要新建查询这个表的sql语句,可以直接用快捷键  ctrl+q  会自动打开查询窗口,并直接写好 sql:select * from (当前打开的表名) 我们直接在后面补全查询条件即可,非常方便。 转载于:https://www.cnblogs.com/libin6505/...