一:了解sql执行各类

Gremlin简介

Gremlin是Apache TinkerPop
框架下的图遍历语言。Gremlin是一种函数式数据流语言,可以使得用户使用简单的法子表明复杂的属性图(property
graph)的遍历或询问。每个Gremlin遍历由一文山会海步骤(可能存在嵌套)组成,每一步都在数据流(data
stream)上举行一个原子操作。

Gremlin包括多少个大旨的操作:

  • map-step
    对数码流中的目标举行转移;
  • filter-step
    对数码流中的对象就行过滤;
  • sideEffect-step
    对数码流进行总结总结;

以下是Gremlin在一部分现象中的具体应用:

  • 1.查找Gremlin朋友的恋人

    g.V().has("name","gremlin").
      out("knows").
      out("knows").
      values("name")
    
  • 2.招来这些由几个对象一起创制的项目

    g.V().match(
      as("a").out("knows").as("b"),
      as("a").out("created").as("c"),
      as("b").out("created").as("c"),
      as("c").in("created").count().is(2)).
    select("c").by("name")
    
  • 3.交由Gremlin的享有上司,直至组长

    g.V().has("name","gremlin").
      repeat(in("manages")).
    until(has("title","ceo")).
      path().by("name")
    
  • 4.收获Gremlin合作者的头衔分布

    g.V().has("name","gremlin").as("a").
      out("created").in("created").
    where(neq("a")).
      groupCount().by("title")
    
  • 5.拿走Gremlin购买产品的相干产品列表并排序

    g.V().has("name","gremlin").
      out("bought").aggregate("stash").
      in("bought").out("bought").
    where(not(within("stash"))).
      groupCount().order(local).by(values,decr)
    
  • 6.获得排行前十的中坚人物

    g.V().hasLabel("person").
      pageRank().
    by("friendRank").
    by(outE("knows")).
      order().by("friendRank",decr).
      limit(10)
    

       
在sql中,第一个被执行的是from语句,每一个步骤都会时有发生一个虚拟表,该表供下一个手续查询时调用,比如语句:select
top 10 column1,colum2,max(column3) from user where id>1 group by
column1,colum2 having
count(column1)>1 order by colum2.

OLTP 和 OLAP遍历

  • 五回编写,到处运行
    Gremlin遵从“两遍编写,到处运行”的计划性法学。这意味不但具备的TinkerPop启用的图形系统都能实施Gremlin遍历,而且每个Gremlin遍历都得以被评估为实时数据库查询或批处理查询。(前者被称之为在线交易流程(OLTP),后者被誉为在线分析流程(OLAP))。

  • 和谐多种图遍历
    那种普遍性是由Gremlin遍历机实现的。这种分布式、基于图形的虚拟机通晓哪些协调多机器图遍历的实施。好处是,用户不需要学习数据库查询语言和域特定的BigData分析语言(例如斯帕克(Spark)(Spark)DSL,MapReduce等)。Gremlin是构建基于图的应用程序所必要的,此外所有都交由Gremlin遍历机处理。
    统计 1

      sqlserver 2005
各样环节简单介绍:

命令式和注脚式遍历

Gremlin遍历可以以命令式(程序式)格局,阐明性(描述性)模式编写,也能够蕴涵命令性和声明性的交集格局编写。

  • 命令式编写模式
    取得Gremlin合作者的下边名字分布:

    g.V().has("name","gremlin").as("a").
      out("created").in("created").
    where(neq("a")).
      in("manages").
      groupCount().by("name")
    

    一个命令式的Gremlin遍历告诉运行器怎样实施遍历中的每一步;然后,遍历器分裂到拥有的“Gremlin”的合作方(去除Gremlin自己);下一步,遍历器走到“Gremlin”合作者的下面(managers),末了依照下边的名字进行总计分发。

据此是命令式的Gremlin遍历,就是它显明地、程序化地告知遍历器“去这里,然后去这里”。

  • 讲明式编写情势
    以下使用阐明式编写形式贯彻了相同的结果:

    g.V().match(
      as("a").has("name","gremlin"),
      as("a").out("created").as("b"),
      as("b").in("created").as("c"),
      as("c").in("manages").as("d"),
    where("a",neq("c"))).
      select("d").
      groupCount().by("name")
    

    声明式的Gremlin遍历并不可以告诉遍历器执行它们的手续的相继,而是允许每个遍历器从一个(可能嵌套的)形式的集结中挑选一个情势来进行。

但是,评释遍历具有额外的便宜,它不仅仅使用了编译时查询计划器(如命令式遍历),而且如故一个周转时查询计划器,按照每个格局的历史总结音讯选拔下一个推行哪个遍历形式

  • 有利这多少个倾向于减弱/过滤大多数多少的格局。

用户可以挑选上述提出的不二法门编写自己的遍历语句。不管咋样,用户的遍历语句都会遵照实际的执行引擎和遍历策略traversal
strategies
被重写。Gremlin为用户提供灵活性表达自己的询问的;图系统也针对具体启用TinkerPop的数据系统进行中用地评估图遍历提供了灵活性。

(8)SELECT (9)DISTINCT  (11)<Top Num> <select list>
(1)FROM [left_table]
(3)<join_type> JOIN <right_table>
(2)ON <join_condition>
(4)WHERE <where_condition>
(5)GROUP BY <group_by_list>
(6)WITH <CUBE | RollUP>
(7)HAVING <having_condition>
(10)ORDER BY <order_by_list>

无缝嵌入主语言

  • 集合主开发语言和图查询语言
    经典数据库查询语言(如SQL)被认为与最后在生育条件中接纳的编程语言截然不同。由此,经典数据库要求开发人员既要编写主编程语言,还要编写数据库相应的询问语言。Gremlin统一了这多少个划分,因为遍历可以用襄助功效整合和嵌套(首要编程语言都襄助)的其它编程语言编写。因而,用户的Gremlin遍历能够行使应用程序语言(主语言,Host
    language)编写,并获益于主语言及其工具(例如类型检查,语法高亮,点到位等)所提供的独到之处。近来存在各样Gremlin语言变体,包括:Gremlin-Java,Gremlin-Groovy,Gremlin-Python,Gremlin-Scala等。

  • 示范程序
    相比较之下二种办法,高低立判:

    public class GremlinTinkerPopExample {
      public void run(String name, String property) {
    
    Graph graph = GraphFactory.open(...);
    GraphTraversalSource g = graph.traversal();
    
    double avg = g.V().has("name",name).
                   out("knows").out("created").
                   values(property).mean().next();
    
    System.out.println("Average rating: " + avg);
      }
    }
    

public class SqlJdbcExample {
  public void run(String name, String property) {

    Connection connection = DriverManager.getConnection(...)
    Statement statement = connection.createStatement();
    ResultSet result = statement.executeQuery(
      "SELECT AVG(pr." + property + ") as AVERAGE FROM PERSONS p1" +
        "INNER JOIN KNOWS k ON k.person1 = p1.id " +
        "INNER JOIN PERSONS p2 ON p2.id = k.person2 " +
        "INNER JOIN CREATED c ON c.person = p2.id " +
        "INNER JOIN PROJECTS pr ON pr.id = c.project " +
          "WHERE p.name = '" + name + "');

    System.out.println("Average rating: " + result.next().getDouble("AVERAGE")
  }
}

   a)各种步骤简介:

参考资料

The Gremlin Graph Traversal Machine and
Language

  1. FROM:对FROM子句中的四个表执行笛Carl积(Cartesian
    product)(交叉联接),生成虚拟表VT1
  2. ON:对VT1使用ON筛选器。只有那个使<join_condition>为真正行才被插入VT2。
  3. OUTER(JOIN):如 果指定了OUTER
    JOIN(绝对于CROSS JOIN 或(INNER JOIN),保留表(preserved
    table:左外部联接把左表标记为保留表,右外部联接把右表标记为保留表,完全外部联接把三个表都标记为保留表)中未找到匹配的就要作为外部行添加到
    VT2,生成VT3.如果FROM子句包含四个以上的表,则对上一个交接生成的结果表和下一个表重复执行步骤1到步骤3,直到处理完所有的表截至。
  4. WHERE:对VT3应用WHERE筛选器。只有使<where_condition>为true的行才被插入VT4.
  5. GROUP BY:按GROUP
    BY子句中的列列表对VT4中的行分组,生成VT5.
  6. CUBE|ROLLUP:把超组(Suppergroups)插入VT5,生成VT6.
  7. HAVING:对VT6应用HAVING筛选器。只有使<having_condition>为true的组才会被插入VT7.
  8. SELECT:处理SELECT列表,产生VT8.
  9. DISTINCT:将再次的行从VT8中移除,暴发VT9.
  10. ORDER BY:将VT9中的行按ORDER BY
    子句中的列列表排序,生成游标(VC10).
  11. TOP:从VC10的起始处采纳指定数量或比重的行,生成表VT11,并回到调用者.

 

  b)标准sql执行各样是:

  1:form 组装来自不同表的数目,如 form user或者,form user as u join
goodsOrder as r on u.id= r.userid

  2:where 过滤符合查询条件的数额,如:id>1000

  3:group by 将查询数据开展分组

  4:使用sum等聚合函数进行总结。

  5:使用having 进行筛选分组。

  6:执行select语种

  7:执行排序语句

  如:select count(gid),gname from shopping_goods where gcid=1 group
by gname having count(gid)>1 order by count(gid) desc

  1:首页查询shopping_goods 表,得到表中的数据

  2:执行where,过滤出gcid=1的商品。

  3:对gname举行分组。

  4:使用聚合函数count(),统计出商品连串为1,不同商品名称的数量.

  5:使用having,过滤出类型为1,商品总括数据超过1的货物

  6:执行select语句

  7:执行order by ,遵照商品数量降序排列。

二:百万数据量优化

  这里只介绍查询和修改的办法,如要是系统优化,需要从表结构,索引,表分区等方面处理。

  1:合理施用索引,在一个大数据量的表中,并不是索引越多越好,索引越多,写操作越慢,提议在偏下字段上创立索引。

  ●在通常举办连接,不过从未点名为外键的列上建立目录,而不通常连接的字段则由优化器自动生成索引。

  ●在屡次举办排序或分组(即开展group by或order by操作)的列上建立目录。

  ●在规范表明式中时时采取的例外值较多的列上建立检索,在不同值少的列上不要确立目录。比如在雇员表的“性别”列上只有“男”与“女”五个不同值,因而就无必要建立目录。假如成立目录不但不会增长查询效用,反而会严重低落更新速度。

  ●如若待排序的列有四个,可以在那多少个列上建立复合索引(compound index)。

  ●使用系统工具。如Informix数据库有一个tbcheck工具,可以在可疑的目录上展开自我批评。在有些数据库服务器上,索引可能失效或者因为一再操作而使得读取效能下降,假诺一个选取索引的查询不明不白地慢下来,可以试着用tbcheck工具检查索引的完整性,必要时开展修复。另外,当数码库表更新大量数码后,删除同样重视建索引可以加强查询速度。

  2:尽量少用(或者不用)sqlserver
自带的函数

  a):如dateadd(month,-1,getdate()),请使用time>’2017-09-19
23:42:44.770 ‘代替dateadd.

  b):如datediff(day,’2017-10-20′,’2017-10-25′),select
datepart(day,getdate());,如需总括五个日子从前的差值,或者取得日期中的整数部分,提出查询完毕后用java程序来总计,不要什么都让数据库来做.

  c:) 如:substring(name,1,3) =
’abc’,指出修改为 name like ‘abc%’

 

  3:尽量不要在 where
子句中对字段举行 null
值判断,否则将导致发动机遗弃选取索引而进展全表扫描,强烈指出where涉及的列,不要留空,创造表时授予起先值

错误
select id from table where name is not null
正确
create table table(name varchar(20) default '')

   4:应尽量避免在 where 子句中动用 != 或 <>
操作符,否则将引擎吐弃采取索引而开展全表扫描。

   

错误
select id from table where id <> 100 

  5:应尽量制止在 where 子句中动用 or
来连接条件,假如一个字段有目录,一个字段没有索引,将导致发动机丢弃接纳索引而举行全表扫描,指出利用unall
来取代or

  

select id from table where num=1 or Name = 'zhangsan'
建议修改为
select id from table where num=1 
unionall 
select id from table where  name = 'zhangsan'

  6:提议使用exists 来顶替in,能用between 就绝不使用in 如:age in
(20,21,22)提出修改为:age between 20 and 22

  

最早此处sql有误,感谢  宝宝心里苦,宝宝不说  的指出。
select id from t where role in (select rid from role where rName = '经理')
建议修改为
select id from t as a where exists (select rid from role  as b where a.role  = b.rid and rName = '经理')

  7:like 的用法

  除了 title  like ‘浦那%’ ,其余使用情势(如:title like  ‘%王%’ title
like ‘%天’)也将造成全表扫描

    8:where 中尽量不要出现表明式总结

  如:

select id from t where num/2 = 100

  应改为:

select id from t where num = 100*2

  9:Update
语句,假使只改变1、2个字段,不要Update全体字段,否则频繁调用会挑起显著的属性消耗,同时带来大气日记。强烈提议修改时使用动态sql语句,类似hibernate中dynamic-update=true,但是hibernate需要将修改对像经过id查询出来,才会动态修改,假设是平日sql,直接组装就足以。

  10:对于多张大数据量(这里几百条尽管大了)的表JOIN,要先分页再JOIN,否则逻辑读会很高,性能很差.

  11:不要写一些未曾意义的查询,如需要生成一个空表结构:

select col1,col2 into #t from t where 1=0

 

  12:尽量拔取数字型字段,若只含数值音讯的字段尽量不要设计为字符型,这会降低查询和连接的性质,并会追加存储开销。这是因为引擎在拍卖查询和连
接时会逐个相比较字符串中每一个字符,而对此数字型而言只需要比较一回就够了。

  13:尽可能的利用 varchar/nvarchar 代替
char/nchar ,因为首先变长字段存储空间小,可以节约存储空间,其次对于查询来说,在一个针锋相对较小的字段内搜寻频率显著要高些。

  14:不提议采纳 select * from t
,用现实的字段列表代替“*”,不要回来用不到的别样字段。

  15:尽量防止使用游标,因为游标的频率较差,倘使游标操作的数目领先1万行,那么就相应考虑改写。

  16:在拥有的蕴藏过程和触发器的上马处设置 SET NOCOUNT ON
,在截至时设置 SET NOCOUNT OFF
。无需在履行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC
消息。

  17:尽量避免大事务操作,提高系统出现能力。并且永不事情嵌套,不要在工作中去调用其他系统的接口,不要在作业中耗时操作,不然死锁并伴你左右

  18:尽量避免向客户端重临大数据量,若数据量过大,应该考虑相应要求是否创造。(笔者曾经处理过,从3000万手机号码库中,模糊查询出上万个手机号码,这种要求是客户硬性要求,就要通过executorservice了,不要平素写sql查)

  19:假设数据库是mysql,一定要使用数据库引擎,不同工作要利用不同的数据库引擎。比如常用的innodb和myisam,innodb协助工作,协助外键,锁是表级锁,缺点是查询速度慢,Myisam
的实践进度更快,性能更好,但不匡助外键,不辅助工作,锁是行锁级。比如日志表,数据量大,强烈提出使用myisam引擎.

 

  以上有些来自网络,有些来自工作中的总括,中期还会圆满,如有错误,请指出,谢谢。