记得在做项指标时候, 听到过一句话, 尽量不要使用子查询,
那么这一篇就来看一下, 那句话是不是是正确的.

总时间范围: 
10000ms

那在那以前, 须求介绍一些概念性东西和mysql对话语的差不离处理.

单个测试点时间范围: 
1000ms

当Mysql Server的连年线程接收到Client发送过来的SQL请求后,
会经过一多级的解说Parse, 举行对应的解析, 然后Mysql会由此询问优化器模块,
根据该Sql所涉嫌到的数据表的连带计算音讯进行测算分析.
然后在汲取一个Mysql自认为最合理最优化的数额访问格局,
也正是我们常说的”执行安排”,
然后依照所得到的实施安排经过调用存款和储蓄引擎接口来收获相应数据.
再对存款和储蓄引擎重返的数量进行有关的处理,
并一Client端所供给的格式作为结果集, 再次来到给Client.

内部存款和储蓄器限制: 
65536kB

统计,注 : 那里所说的计算数据, 是大家透过 Analyze
table命令公告Mysql对表的相干数据作分析之后, 所获取到的片段数码总括量.
这一个数据对Mysql优化器而言是可怜首要的, 优化器所生成的推行安顿的上下,
首若是由这个总括数据所主宰的.

  1. 建表

    create table User(
      Id int not null PRIMARY key auto_increment ,
      NickName varchar(50) comment ‘用户外号’,
      Sex int comment ‘性别’,
      Sign varchar(50) comment ‘用户签名’,
      Birthday datetime comment ‘用户生日’,
      CreateTime datetime comment ‘创设时间’
    ) default charset=utf8 comment ‘用户表’;

    create table UserGroup(
      Id int not null PRIMARY key auto_increment ,
      UserId int not null comment ‘user Id’,
      GroupId int not null comment ‘用户组Id’,
      CreateTime datetime comment ‘成立时间’,
      – key index_groupid(GroupId) using btree,
      key index_userid(groupid, UserId) using btree
    ) default charset=utf8 comment ‘用户组表’;

  2. 常备不懈数据

    var conStr = ConfigurationManager.ConnectionStrings[“ConStr”].ToString();
    using (IDbConnection conn = new MySqlConnection(conStr))
    {

     Stopwatch watch = new Stopwatch();
     var sql = string.Empty;
     var names = new string[] { "非", "想", "红", "帝", "德", "看", "梅", "插", "兔" };
     Random ran = new Random();  
     var insertSql = @" insert into User(NickName,Sex,Sign, Birthday, CreateTime) values(@NickName,@Sex,@Sign, @Birthday, @CreateTime); 
     INSERT INTO usergroup  (UserId,  GroupId,  CreateTime )  VALUES (LAST_INSERT_ID() ,   @GroupId,  @CreateTime);";
     watch.Start();
     if (conn.State == ConnectionState.Closed)
     {
         conn.Open();
     }
    
     var tran = conn.BeginTransaction();
     for (int i = 0; i < 100000; i++)
     {
         var param = new { NickName = names[ran.Next(9)] + names[ran.Next(9)] + i, Sign = names[ran.Next(9)] + names[ran.Next(9)], CreateTime = DateTime.Now, Birthday = DateTime.Now.AddYears(ran.Next(10, 30)), Sex = i % 2, GroupId = ran.Next(1, 100) };
         conn.Execute(insertSql, param, tran);
     }
     tran.Commit();
    
     conn.Dispose();
     watch.Stop();
     Console.WriteLine(watch.ElapsedMilliseconds);
    

    }

描述
LGTB 近年来在学分块,不过他太菜了,分的块数量太多她就混乱了,所以只能分成 3

此间笔者插入了5000条数据, group分了九十六个组, 随机的. 

前几日他获得了一个数组,他霍然也想把它分块,他想驾驭,把这些数组分成 3
块,块可以为空。要是 3 块各自的和中的最大值最小

 

请输出分完之后 3 块中的最大值

  1. 查询sql

    explain
    select user.id, user.nickname from usergroup
    left join user on usergroup.UserId = user.Id
    where usergroup.groupid = 1
    order by usergroup.UserId desc
    limit 100, 20;

    explain
    select user.id, user.nickname
    from (select id, userid from usergroup where groupid = 1 order by userid limit 100, 20) t
    left join user on t.UserId = user.id ;

    explain
    select user.id, user.nickname
    from (select id, userid from usergroup where groupid = 1 order by userid ) t
    left join user on t.UserId = user.id
    limit 100, 20;

输入
输入第①行蕴涵一个整数 n 代表数组大小
接下去 n 个整数 a1 , a2 , …, a n ,代表数组

 

输出
输出包蕴 1 个整数,代表分块完结后 3 块中的最大值

第③句和第壹句都采纳到了子查询, 不一样之处再与, 第三句是先获得20条数据,
然后以此来与user表关联的

样例输入
10
2 5 1 4 7 3 6 2 5 1

 

样例输出
14

  1. 分析

提示
对于 40% 的数据,1 ≤ n ≤ 10
对于 70% 的数据,1 ≤ n ≤ 1e3
对于 100% 的数据,1 ≤ n ≤ 1e5 , 1 ≤ ai ≤ 1e7

一千00条数据景况下 : 

先看率先句

大局题号
7414

统计 1

交给次数
14

 

品尝人数
7

再看第2句

通过人数
2

统计 2

你的交由记录

#

结果

时间

4

Accepted

07-16

3

Wrong Answer

07-16

2

Time Limit
Exceeded

07-16

1

Time Limit
Exceeded

07-16

 

– ©2002-2013 POJ 沪ICP备12005590号-3

 

 

 

二分答案秒过

而后写二分答案不写l++了,慢的要死。。

 

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #define lli long long int 
 6 using namespace std;
 7 const lli MAXN=100000001;
 8 void read(lli &n)
 9 {
10     char c='+';lli x=0;bool flag=0;
11     while(c<'0'||c>'9'){c=getchar();if(c=='-')flag=1;}
12     while(c>='0'&&c<='9')
13     x=(x<<1)+(x<<3)+c-48,c=getchar();
14     flag==1?n=-x:n=x;
15 }
16 lli a[MAXN];
17 lli l,r;
18 lli n;
19 bool pd(lli num)
20 {
21     lli now=0;
22     lli tot=0;
23     for(lli i=1;i<=n;i++)
24     {
25         if(now+a[i]<num)
26             now+=a[i];
27         else if(now+a[i]==num)
28             tot++,now=0;
29         else if(now+a[i]>num)
30             tot++,now=a[i];
31     }
32     if(now)
33         tot++;
34     if(tot>3)
35         return 0;
36     else 
37         return 1;
38 }
39 int  main()
40 {
41     read(n);
42     for(lli i=1;i<=n;i++)
43         read(a[i]),r+=a[i],l=max(l,a[i]);
44     while(l<=r)
45     {
46         lli mid=(l+r)>>1;
47         if(pd(mid))
48             r=mid-1;
49         else 
50             l=mid+1;
51     }
52     printf("%lld",l);
53     return 0;
54 }

 

 

第三句

统计 3

从上边三幅图看, 好像能来看点什么了.

率先看她们的 rows, 第贰句最多, 加起来有一千多了, 另两句加起来都以996.
但是本身想说的是, 这里并不是看rows的和是不怎么. 正确的艺术是,
从id大的语句早先看, id相同的口舌, 从上到下依次执行.

那先看第三句的id=2的讲话和第1句的id=1的话语, 一模一样的.
他们都以从usergroup表中筛选数据, 并且能获取一致的结果集A.

如上所述他们都以基于相同的结果集去开始展览操作, 接下来就有分别了.

先看率先句, 再结实集A的底蕴上, 去左连接表user, 并筛选出最后的数量,
重回给客户端.

这第贰句呢, 是在A的底子上, 再一次筛选数据, 获得须要的数据, 然后拿那些多少,
去与user表左连接, 得到终极结果.

从地方来看, 执行安排中, 第二种实施安插, 特别高效. 

 要是可以通过子查询, 大幅度压缩查询范围, 能够设想使用子查询语句. 

 

 参考:

  Mysql质量优化explain