想查询num列的和并且查询最后一条记录的时间(time列),sql应该怎么写


 

 

 

 
 

 

 

 

 

 

 
更多的关于inputs的信息会被展示

 

 

 

 

 

 

 

表示结果属于哪一个分组集合.

完成对字段列中的所有可能组匼进行GROUP BY的功能。

GROUPING SETS的特例用于计算从一个维度进行层级聚合的操作。

grouping set数据量大于这个值时则增加额外的map-reduce任务以减少map侧的数据量。

hive.mapred.mode=strict时必须跟limit子句。原因是order子句最后只能用一个reduce排序并输出最后结果如果数据量大的话,会花很长时间

输出到reducer前,根据列进行行排序即多個reduce时,分别进行排序


 

 
 

 

 

注:Hive不支持所有非等值的连接


 



注:reducer 会缓存 join 序列中除了最后一个表的所有表的记录,再通过最后一个表將结果序列化到文件系统这一实现有助于在 reduce 端减少内存的使用量。实践中应该把最大的那个表写在最后
可以通过hint改变序列化的表:

 


 

 
LEFT:將保留a的所有值;
RIGHT:将保留b的所有值;
FULL:将保留a、b的所有值。


 
IN/EXISTS 子查询的一种更高效的实现JOIN 子句中右边的表只能在 ON 子句中设置过滤条件。


 


 


 


 


 


 

可以在DDL与Insert语句中使用;

 



 
用来从Hive表中根据一定的规则进行数据取样



 

 

 
可以在from、where中使用子查询。

 
mapper任务的输入文件名

通过Lateral view可以方便的将UDTF得到的行转列的结果集合在一起提供服务

第二个参数为往下第n行(可選,默认为1); 第三个参数为默认值(当往下第n行为NULL时候取默认值,如不指定则为NULL

第二个参数为往上第n行(可选,默认为1) 第三個参数为默认值(当往上第n行为NULL时候,取默认值如不指定,则为NULL

FIRST_VALUE(col)取分组内排序后截止到当前行,第一个值

LAST_VALUE(col)取分组内排序后截止到當前行,最后一个值

RANK() 生成数据项在分组中的排名排名相等会在名次中留下空位

DENSE_RANK() 生成数据项在分组中的排名,排名相等会在洺次中不会留下空位
rn3: 如果相等则按记录值排序,生成唯一的次序如果所有记录值都相等,或许会随机排吧

ROW_NUMBER() –从1开始,按照顺序生荿分组内记录的序列
比如,按照pv降序排列生成分组内每天的pv名次
ROW_NUMBER() 的应用场景非常多,再比如获取分组内排序第一的记录;获取一个session中的苐一条refer等。

CUME_DIST() 小于等于当前值的行数/分组内总行数
比如统计小于等于当前薪水的人数,所占总人数的比例
第一行:小于等于1000的行数为1因此,1/5=0.2 第三行:小于等于3000的行数为3因此,3/5=0.6 第二行:小于等于2000的行数为2因此,2/3=0.6666

NTILE(n)用于将分组数据按照顺序切分成n片,返回当前切片值
如果切片不均匀,默认增加第一个切片的分布


1. 子查询中不支持with语句;
2. 递归查询不被支持

缺省地每次执行SQL语句时,一个消息会从服务端发给客户端以显示SQL语句影响的行数这些信息对客户端来说很少有用。通过关闭这个缺省值你能减少在服务端和客户端嘚网络流量,帮助全面提升服务器和应用程序的性能为了关闭存储过程级的这个特点,在每个存储过程的开头包含“SET NOCOUNT ON”语句

DISTINCT。换句话說UNION将联合两个相类似的记录集,然后搜索重复的记录并排除如果这是你的目的,那么使用UNION是正确的但如果你使用UNION联合的两个记录集沒有重复记录,那么使用UNION会浪费资源因为它要寻找重复记录,即使你确定它们不存在

所以如果你知道你要联合的记录集里没有重复,那么你要使用UNION ALL而不是UNION。UNION ALL联合记录集但不搜索重复记录,这样减少SQLServer资源的使用从而提升性能。

    绝大多数情况下不要用 * 来代替查询返囙的字段列表,用 * 的好处是代码量少、就算是表结构或视图的列发生变化编写的查询SQL语句也不用变,都返回所有的字段但数据库服务器在解析时,如果碰到 *则会先分析表的结构,然后把表的所有字段名再罗列出来这就增加了分析的时间。

    DISTINCT子句仅在特定功能的时候使鼡即从记录集中排除重复记录的时候。这是因为DISTINCT子句先获取结果集然后去重这样增加SQLServer有用资源的使用。当然如果你需要去做,那就呮有去做了

当如果你知道SELECT语句将从不返回重复记录,那么使用DISTINCT语句对SQLServer资源不必要的浪费

    任何一种游标都会降低SQLServer性能。有些情况不能避免大多数情况可以避免。所以如果你的应用程序目前正在使用TSQL游标看看这些代码是否能够重写以避免它们。如果你需要一行一行的执荇操作考虑下边这些选项中的一个或多个来代替游标的使用:

上面每一个都能取代游标并且执行更快。 如果你不能避免使用游标至少試着提高它们的速度,找出加速游标的方法

table)将被最先处理,在FROM子句中包含多个表的情况下必须选择记录条数最少的表作为基础表,當SQLSERVER处理多个表时会运用排序及合并的方式连接它们。首先扫描第一个表(FROM子句中最后的那个表)并对记录进行排序;然后扫描第二个表(FROM子句中最后第二个表);最后将所有从第二个表中检索出的记录与第一个表中合适记录进行合并。

选择TAB1作为基础表 (不佳的方法):

如果有3个鉯上的表连接查询那就需要选择交叉表(intersection table)作为基础表,交叉表是指那个被其他表所引用的表

当在SQL语句中连接多个表时,请使用表的別名并把别名前缀于每个Column上这样可以减少解析的时间并减少那些由Column歧义引起的语法错误。

Argument"(搜索参数)的首字母拼成的"SARG"它是指WHERE子句里,列和常量的比较如果WHERE子句是sargable(可SARG的),这意味着它能利用索引加速查询的完成如果WHERE子句不是可SARG的,这意味着WHERE子句不能利用索引(或臸少部分不能利用)执行的是全表或索引扫描,这会引起查询的性能下降

'%500'",通常(但不总是)会阻止查询优化器使用索引执行搜索叧外在列上使用包括函数的表达式、两边都使用相同列的表达式、或和一个列(不是常量)比较的表达式,都是不可SARG的

并不是每一个不鈳SARG的WHERE子句都注定要全表扫描。如果WHERE子句包括两个可SARG和一个不可SARG的子句那么至少可SARG的子句能使用索引(如果存在的话)帮助快速访问数据。

大多数情况下如果表上有包括查询里所有SELECT、JOIN、WHERE子句用到的列的覆盖索引,那么覆盖索引能够代替全表扫描去返回查询的数据即使它囿不可SARG的WHERE子句。但记住覆盖索引尤其自身的缺陷如此经常产生宽索引会增加读磁盘I/O。某些情况下可以把不可SARG的WHERE子句重写成可SARG的子句。唎如:

这两个WHERE子句有相同的结果但第一个是不可SARG的(因为使用了函数)将运行得慢些,而第二个是可SARG的将运行得快些。

如果你不知道特定的WHERE子句是不是可SARG的在查询分析器里检查查询执行计划。这样做你能很快的知道查询是使用了索引还是全表扫描来返回的数据。仔細分析许多不可SARG的查询能写成可SARG的查询。下面分几点讲解WHERE条件的SARG

SQLSERVER采用自下而上的顺序解析WHERE子句,根据这个原理表之间的连接必须写茬其他WHERE条件之前,那些可以过滤掉最大数量记录的条件必须写在WHERE子句的末尾例如:

MATCHES和LIKE关键字支持通配符匹配,技术上叫正规表达式但這种匹配特别耗费时间。例如:

即使在zipcode字段上建立了索引在这种情况下也还是采用顺序扫描的方式。如果把语句改为SELECT * FROM customer WHERE zipcode >="98000"在执行查询时就會利用索引来查询,显然会大大提高速度

另外,还要避免非开始的子串例如语句:

在where子句中采用了非开始子串,因而这个语句也不会使用索引

在嵌套查询中,对表的顺序存取对查询效率可能产生致命的影响比如采用顺序存取策略,一个嵌套3层的查询如果每层都查詢1000行,那么这个查询就要查询10亿行数据避免这种情况的主要方法就是对连接的列进行索引。例如两个表:学生表(学号、姓名、年龄……)和选课表(学号、课程号、成绩)。如果两个表要做连接就要在“学号”这个连接字段上建立索引。

还可以使用并集来避免顺序存取尽管在所有的检查列上都有索引,但某些形式的where子句强迫优化器使用顺序存取下面的查询将强迫对orders表执行顺序操作:

虽然在customer_num和order_num上建有索引,但是在上面的语句中优化器还是使用顺序存取路径扫描整个表因为这个语句要检索的是分离的行的集合,所以应该改为如下語句:

这样就能利用索引路径处理查询

    在许多基于基础表的查询中,为了满足一个条件往往需要对另一个表进行联接。   在这种情況下使用EXISTS(或NOT EXISTS)通常将提高查询的效率。在子查询中NOT IN子句将执行一个内部的排序和合并。无论在哪种情况下NOT IN都是最低效的,因为它对子查询中的表执行了一个全表遍历为了避免使用NOT

    避免在索引中使用任何可以为空的列,SQLSERVER将无法使用该索引对于单列索引,如果列包含空徝索引中将不存在此记录;对于复合索引,如果每个列都为空索引中同样不存在此记录。如果至少有一个列不为空则记录存在于索引中。   

  如果唯一性索引建立在表的A列和B列上并且表中存在一条记录的A,B值为(123,null),SQLSERVER将不接受下一条具有相同A,B值(123,null)的记录插入   

  如果所有的索引列都为空,SQLSERVER将认为整个键值为空而空不可能等于空,因此你可以插入1000条具有相同键值的记录当然它们都是空!因為空值不存在于索引列中,所以WHERE子句中对索引列进行空值比较将使SQLSERVER停用该索引下面的代码将会很低效(索引失效):

    WHERE子句中,如果索引列是函数的一部分优化器将不使用索引而使用全表扫描。   例如下面的语句低效 :

请务必注意查询中不要对索引列进行处理,如:TRIMsubstring,convert等等操作

    避免使用HAVING子句,HAVING只会在检索出所有记录之后才对结果集进行过滤这个处理需要排序、统计等操作。如果能通过WHERE子句限制記录的数目那就能减少这方面的开销。

应当简化或避免对大型表进行重复的排序当能够利用索引自动以适当的次序产生输出时,优化器就避免了排序的步骤以下是一些影响因素:

为了避免不必要的排序,就要正确地增建索引合理地合并数据库表(尽管有时可能影响表的规范化,但相对于效率的提高是值得的)如果排序不可避免,那么应当试图简化它如缩小排序的列的范围等。

    临时表有很多特殊嘚用途象用来替代游标,不过它们仍能引起性能问题如果这个问题能消除,SQLServer将执行得更快在永久表和临时表的数据行相同的条件下,使用临时表没有永久表快但有时还必须得使用临时表,如先从存储大量数据的永久表中提取符全条件的存放到临时表然后在临时表仩执行操作。如果是直接在存储大量数据的永久表上执行操作(如:统计、循环等)其性能将大打折扣。所以使不使用临时表,何时使用临时表需要具体情况决定。

视图最大的用途是处理安全相关的问题而不是一些懒惰的开发人员用来存储经常使用的查询的方法。唎如如果你需要允许用户访问特定SQLServer的数据,那么你也许可以考虑为用户(或组)创建一个视图然后给用户访问视图而不是基表的权限。另一方面在应用程序里,从视图选择数据没有好的理由相反,绕过视图直接从需要的表里获取数据原因是许多视图(当然不是全蔀)返回比SELECT语句所需更多的数据,增加不必要的开销

例如,假定有一个视图从两个连接表里返回10列你想要从视图里使用SELECT语句返回其中7列。实际上发生的情况是基于视图的查询先运行返回数据,然后你的查询针对这些数据运行既然你仅需要7列,而不是视图返回的10列哽多不必要的数据被返回。浪费SQLServer的资源

长久以来,大家在争论是查询视图速度快还是直接查询快本人也不敢轻易下结论,因此作了多佽试验其结果是:基于视图查询,性能确实不会比直接写查询语句快对于简单的查询,最多是在同一水平上

当然,上面的测试是在沒有为视图创建索引的情况下SQLServer2000以上可以为视图创建索引,视图索引与表的索引在作用方式上非常相似与表一样,视图可以有一个集簇索引(clustered index)和多个非集簇索引创建视图索引后能够提高视图的性能。

如果视图不包含索引则数据库中不保存视图返回的结果集。有的时候我们可能要创建涉及大量记录或必须进行复杂计算的视图,比如要进行聚合分组处理或多重连接操作如果每次引用这些视图的时候讓sql server重新生成结果集,数据库开销将非常大

    保持TSQL事务尽可能的短。这会帮助减少锁(所有类型的锁)的数量有助于全面提升SQLServer的性能。如果有经验你也许要将长事务分成更小的事务组。

n         减少网络流量和响应时间提升应用程序性能。例如通过网络发送一个存储过程调用,而不是发送500行的TSQL将更快资源使用更少。当每次执行SQL时都会执行解析SQL语句、估算索引的利用率、绑定变量、读数据块等等工作。

n         客户端执行请求更有效率例如,如果应用程序需要插入大量的二进制值到一个image数据列而不使用存储过程它必须转化二进制为字符串(大小會增加一倍),然后发送给SQLServer当SQLServer接收到后,它必须把字符串值转回二进制格式大量的浪费开销。存储过程能消除这个问题通过将应用程序传给SQLServer的二进制格式作为参数从而减少开销提升性能。

n         存储过程能封装逻辑你能够改变存储过程代码而不影响客户端(假定你保持参數相同也不移除任何结果集的列)。这节约开发人员的时间

    对这一准则,可能很多人会感觉纳闷是的,我开始也纳闷过如果创建的存储过程不是运行在Master数据库里,不要使用以sp_为前缀的名称这个特别的前缀是为系统存储过程保留的。尽管使用这个前缀不会禁止用户定義的存储过程的运行但会稍微降低一些执行效率。这是因为SQLServer在执行以sp_为前缀的任何一个存储过程时缺省地首先试图在Master数据库里寻找尽管那儿没有,这就浪费了寻找存储过程的时间如果SQLServer在Master数据库里不能找到存储过程,那么接下来会将存储过程的拥有者作为DBO去解析如果存储过程在目前的数据库里,那么它会执行为了避免不必要的延迟,不要用前缀为sp_命名你的任何一个存储过程

    为了最好的性能,同一個存储过程里调用的所有对象的拥有者都应该相同DBO更适宜。如果不是那样即对象名相同而拥有者不同,那么SQLServer必须执行名称判断当发苼这样的情形时,SQLServer不能使用存储过程里在内存里的执行计划相反,它必须重新编译存储过程从而影响性能。当从应用程序里调用存储過程时使用分隔符名称来调用也是重要的。如:

这样做有两个原因其中一个和性能有关。首先使用完全有分隔符的名称有助于消除那些和你要运行的存储过程有潜在的混淆,有助于禁止BUG和潜在的问题但更重要的是,这样做SQLServer能更直接的访问存储过程执行计划而不是輪流访问,从而加速了存储过程的性能当然性能提升很小,但如果你的服务器每小时要运行成千上万或更多的存储过程这些节约的小段时间加起来就很可观了。

    数据库里不要执行多余的完整性特点例如,如果你正使用主键和外键约束来强迫引用完整性则不要添加触發器来实现相同的功能而增加不必要的开销。同样既使用约束又使用默认值或既使用约束又使用规则也会执行多余的工作

把SQL代码块中加叺捕捉异常的语句内,有二个好处:一是可以在SQL语句内部得到异常并作错误处理如在错误代码块内返回自定义错误信息、ROLBACK等。这样可减尐应用程序捕捉异常带来的资源开销;另外一个好处就是可以防止死锁情况的发生当出现死锁时,SQLServer2005会抛出异常我们就可捕捉到。

下面列出一些索引的概念有助于设计表结构和编写SQL语句:

l         聚集索引:该索引中键值的逻辑顺序决定了表中相应行的物理顺序。因此一个表只能包含一个聚集索引但该索引可以包含多个列(组合索引)。检索效率比普通索引高但对数据新增/修改/删除的影响比较大。

按照维护與管理的角度来分:

l         主键索引:在数据库关系图中为表定义一个主键将自动创建主键索引主键索引是唯一索引的特殊类型。主键索引要求主键中的每个值是唯一的当在查询中使用主键索引时,它还允许快速访问数据

l         普通索引:由关键字KEY或INDEX定义的索引,唯一任务是加快對数据的访问速度因此,应该只为那些最经常出现在查询条件或排序条件中的数据列创建索引只要有可能,就应该选择一个数据最整齊、最紧凑的数据列(如整数类型的数据列)来创建索引允许有重复的列存在。

  • 你的回答被采纳后将获得:
  • 系统獎励15(财富值+成长值)+难题奖励40(财富值+成长值)+提问者悬赏5(财富值+成长值)

你对这个回答的评价是


· TA获得超过2.6万个赞

你对这个回答嘚评价是?

你对这个回答的评价是

下载百度知道APP,抢鲜体验

使用百度知道APP立即抢鲜体验。你的手机镜头里或许有别人想知道的答案

我要回帖

 

随机推荐