说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

数据量比较大时的查询问题,C#的!在线等,100分!

编辑:说三道四文库 发布时间:2018-08-17 06:05
HTML文档下载 WORD文档下载 PDF文档下载

sql语句:

sql = "SELECT country.countryname,SELECT COUNT(Personal_ID) FROM Population_Info WHERE SUBSTRING   (Population_Info.Personal_ID,1,6) = country.countryid) AS 'all',
       (SELECT COUNT(Personal_ID) FROM Population_Info WHERE SUBSTRING(Population_Info.Personal_ID,1,6) = country.countryid AND Population_Info.Gender=1 ) AS 'male',
       (SELECT COUNT(Personal_ID) FROM Population_Info WHERE SUBSTRING(Population_Info.Personal_ID,1,6) = country.countryid AND Population_Info.Gender=2 ) AS 'female' FROM country"

这个sql的意思是从country(地区)表中查这个地区内的总人口all,男性人口male,女性人口female总数,人口的总数是从Population_Info这个表里查,人口有个Personal_ID,一共是18位,前六位SUBSTRING(Population_Info.Personal_ID,1,6),等于地区表country中的地区ID,这个sql语句在数据量小的时候没问题,但现在数据上到70多万了,

就显示出错误:未将对象引用设置到对象的实例

C#中跟踪到下面的代码出错:adapter.Fill(DS);

以下是C#代码:

QueryResult = exesql.GetData(sql);
listrecord.DataSource = QueryResult.DefaultView;
listrecord.DataBind();

listrecord是个Repeater控件,请问是什么原因哪?这个sql我在sql server的查询分析器里测试了,能查出来,就是效率不太高,慢点,但能查出来,着急解决,分不够再加,谢谢!
将查询语句做成视图Creat Viw
补充:
exesql.GetData(sql);中的GetData方法代码如下

public DataTable GetData(string StrSql)
{
DataSet DS=new DataSet();
string strconn=StrConn;
SqlConnection connection=new SqlConnection(strconn);
SqlDataAdapter adapter=new SqlDataAdapter(StrSql,connection);
try
{
connection.Open();
adapter.Fill(DS);
}
catch(SqlException e)
{
System.Console.Write(e.ToString());
}
finally
{
connection.Close();
}


if(DS.Tables.Count!=0)
{
return DS.Tables[0];
}
else
return null;
}
可能查询超时导致fill不能成功,优化数据库
1. 理论上不会太慢

2. 要给Personal_ID建立一个索引

3. 你的查询应当做分组Group By, 而不是使用子查询(这是罪魁祸首)
建议做视图或写为存储过程。
另外数据库设计上也存在问题,

如果经常需要查 SUBSTRING(Population_Info.Personal_ID,1,6)

应当作为一个独立的字段,这个市行政区划码吧,哈 :)
我个人觉得你的SQL语句会有问题,应该有更好的方法的,如Group By 分组
试试这个SQL, 注意把下面的 mid,换成你的substring,

另外如果有其它语法问题也请改一下,因为我是在Access中写的

Select CountryName, XP1.N, XP2.N, XP3.N
    From (((Country As C1
Left Join
(
Select mid(P1.Personal_ID,1,6) As C, Count(*) As N
    From Population_Info As P1
        Group By mid(P1.Personal_ID,1,6)
) As XP1 On C1.Countryid = XP1.C)
Left Join
(
Select mid(P2.Personal_ID,1,6) As C, Count(*) As N
    From Population_Info As P2 Where P2.Gender=1
        Group By mid(P2.Personal_ID,1,6)
) As XP2 On C1.CountryID = XP2.C)
Left Join
(
Select mid(P3.Personal_ID,1,6) As C, Count(*) As N
    From Population_Info As P3 Where P3.Gender=2
        Group By mid(P3.Personal_ID,1,6)
)  As XP3 On C1.CountryID = XP3.C)
就是先统计出你需要的数据,然后让Country表和统计表做左连接
SELECT a.countryid,a.countryname,
sum(Case when b.Gender is null then 0 else 1 end) as 'all',
sum(Case when b.Gender=1 then 1 else 0 end) as 'male',
sum(Case when b.Gender=2 then 1 else 0 end) as 'female',
from country a
left join Population_Info b on a.countryid=SUBSTRING(b.Personal_ID,1,6)
Group by a.countryid,a.countryname
Order by a.countryid
用上面的SQL语句在查询分析器里试试效率
up
哈。。。谢谢大家

看来都很有兴趣,我已经用tiaoci(我挑刺,我快乐) 兄弟的办法实现了

谢谢tiaoci, tengjian1981(Fly) 的方法我没试,不过看起来也不错

有个小问题再请教一下,左连接是什么意思啊?

结帐了。。。。
左连接就是用关联条件将两张表连接成一张表处理,查看SQLServer的帮助吧
UP``````````````````
对,就是查询超时引起的,所以没有实例化。
优化吧,兄弟
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘