fredxiong

导航

统计
公告
 

置顶随笔

摘要: 最近自已开发了一个自定义表单管理系统,就是让用户自己定制自己的表,字段,通过此系统自动生成表,并提供数据录入与修改的界面。我参照SQL Server帮助文档中Alter Table命令,对表结构进行修改时,出错了一些错误,下面特针对此常见错误做出详细说明,文章中有引用作者[Leo]的方法例题代码 Code highlighting produced by Actipro CodeHighlight...阅读全文
posted @ 2009-12-12 11:09 fredxiong 阅读(214) 评论(0) 编辑

2011年6月10日

Private Sub ShowList()
    
    
If m_DataSource Is Nothing Then Exit Sub
    
If m_DataSource.State = 0 Then Exit Sub
    
If m_DataSource.RecordCount = 0 Then Exit Sub
    
    
'将combobox locked,以避免combobox自动清空
'
    txtData.Locked = True
    If Not InitList() Then Exit Sub
    
'取得usercontrol的位置
    Dim rcWnd As rect
    
Dim cxScreen As Long
    
Dim cyScreen As Long
    
    GetWindowRect UserControl.hwnd, rcWnd
    mdlCommon.rcControl 
= rcWnd
    
' Screen.TwipsPerPixelX 为将pixel座标转成Twip座标
    frmList.Left = rcWnd.Left * Screen.TwipsPerPixelX
    frmList.Top 
= rcWnd.Bottom * Screen.TwipsPerPixelY
    
    
'此段code为判断list是否已超出Screen area
    '若超出,则改变其show 出方向、座标
    cxScreen = GetSystemMetrics(SM_CXSCREEN)
    
If cxScreen And _
        (frmList.Left 
+ frmList.Width) > cxScreen * Screen.TwipsPerPixelX Then
        frmList.Left 
= cxScreen * Screen.TwipsPerPixelX - frmList.Width - 100
    
End If
    cyScreen 
= GetSystemMetrics(SM_CYSCREEN)
    
If cyScreen And _
        (frmList.Top 
+ frmList.Height + 600> cyScreen * Screen.TwipsPerPixelY Then
        frmList.Top 
= rcWnd.Top * Screen.TwipsPerPixelY - frmList.Height
    
End If
    
'0122
    frmList.Show vbModal, Me
    
If strVersion <> "2000" Then
        frmList.Show vbModal, Me
        VBA.SendKeys 
"{TAB}"
        
Call keybd_event(VK_SHIFT, 0, KEYEVENTF_EXTENDEDKEY, 0)
        
Call keybd_event(VK_TAB, 0, KEYEVENTF_EXTENDEDKEY, 0)
        
Call keybd_event(VK_TAB, 0, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0)
        
Call keybd_event(VK_SHIFT, 0, KEYEVENTF_EXTENDEDKEY Or KEYEVENTF_KEYUP, 0)
    
End If
End Sub
posted @ 2011-06-10 01:06 fredxiong 阅读(21) 评论(0) 编辑

2010年10月30日

來源:http://0791.teambuy.com.cn/digital/showcpnews.php?newsid=3572

以此献给双显卡切换未成功的朋友们,希望你们可以解决问题!
我的配置是THINKPAD 2784 A34 + WINDOWS7旗舰版
方法一:

在联想网站中下载显卡驱动Switchable Graphics,此安装程序是包含独立显卡和集成显卡驱动的,安装后就可以在任务栏的电池图标上单击右键,在弹出的菜单中有一项“可切换显卡”就是双显卡切换的开关了,选择节能是使用X4500集成显卡,选择高性能是使用ATI 3470独立显卡,如果没有出现“可切换显卡”,就用下面的方法。

方法二:
打开控制面板--程序和功能,卸载所有带有ATI字样的程序和ThinkPad 电源管理 和ThinkPad power manager driver(电源管理软件和驱动)。然后右键点击计算机图标,选择管理--设备管理器,将所有显卡设备全部卸载(包括集成显卡,右键点击选择卸载)。之后重新启动电脑按照以下步骤操作来手动安装win7系统下的驱动。

1.开机出现Think启动画面时按键盘上的F1键进入BIOS界面,BIOS里设置Default Primary Video Device为PCI Express,设置Graphics Device为Discrete(按F5或者F6可以修改),OS Detection for Switchable Graphics为Disabled;
2.安装主板芯片组驱动(Intel Chipset Drivers)
http://think.lenovo.com.cn/support/driver/detail.aspx?docID=DR1255924537956&docTypeID=DOC_TYPE_DRIVER
3.安装Intel Matrix Storage Manager硬盘驱动程序
http://think.lenovo.com.cn/support/driver/detail.aspx?docID=DR1197539101703&docTypeID=DOC_TYPE_DRIVER
4.安装ACPI电源驱动,就是Power Manager Driver;
http://think.lenovo.com.cn/support/driver/detail.aspx?docID=DR1197863947328&docTypeID=DOC_TYPE_DRIVER
5.安装Lenovo System Interface Driver;同时安装hotkey
http://think.lenovo.com.cn/support/driver/detail.aspx?docID=DR1217231721126&docTypeID=DOC_TYPE_DRIVER
http://think.lenovo.com.cn/support/driver/detail.aspx?docID=DR1216893127788&docTypeID=DOC_TYPE_DRIVER
6.安装Power Manager电源管理软件
http://think.lenovo.com.cn/support/driver/detail.aspx?docID=DR1197862934453&docTypeID=DOC_TYPE_DRIVER
7.重启电脑。然后安装R400自带的ATI显卡驱动,注意此时需在设备管理器中找到ATI显卡并手动指定路径安装,指向C:\\DRIVERS\\WIN\\VIDEO\\Bin即可。
显卡驱动可以在以下网址下载,双击解压后不要安装。(取消自动安装的选项)
http://think.lenovo.com.cn/support/driver/detail.aspx?docID=DR1255922090378&docTypeID=DOC_TYPE_DRIVER
8.重启进入BIOS,设置Default Primary Video Device为Internal,设置Graphics Device为Intergrated,OS Detection for Switchable Graphics为Disabled
9.启动进入Win7后,系统会自动安装Mobile Intel 45 Express显卡驱动(需要等待一段时间后才可以自动安装驱动,有时360会弹出提示,点确定),但这个显卡驱动不是Intel的,而是前面安装的ATI驱动包里自带的。如果安装了Intel的X4500驱动,就没办法实现双显卡切换了,这一点是整个安装过程的重点,在之前安装ATI驱动的过程中,ATI驱动的安装程序已经同时安装了X4500的驱动。
10.安装后重启电脑,让系统自动安装。
11. 再重启一次,重启后进入BIOS,设置Graphics Device为Switchable,OS Detection for Switchable Graphics为Ensabled;
12.启动进入Win7,这时会看起来像没有装上显卡驱动一样,仍然像上面一样让系统自动安装显卡驱动,完成后重启;
13.进入Win7后在任务栏的电池图标上单击左键,在弹出的黑色菜单下最后一项“可切换显卡”就是双显卡切换的开关了。选择节能是使用X4500集成显卡,选择高性能是使用ATI 3470独立显卡,在显卡切换的时候屏幕会黑一下。如果你打开设备管理器,就可以看到两个显卡都出现在显示适配器下面,而且上面都没有黄色叹号。

按照网上搜索的方法,到这里就结束了,正常是可以切换显卡的,但是我的却不能,原因是由于绿色电池点右键时没有“可切换显卡”选项。
此时在点开始—运行中输入dxdiag — 显示,可以看到驱动不是HD3400,而是INTER的。
我是这样操作的:
首先进入设备管理器将当前的集成显卡上右键—禁用,禁用后屏幕会变黑。重启电脑后会自动切换到独立显卡,但是好像还是没有安装驱动一样,此时将独立显卡驱动解压缩,点击setup正常安装(如果正常的话解压缩后会自动提示是否安装,如果没有,就到C:\\DRIVERS\\WIN\\VIDEO中执行setup手动安装),安装完毕重启电脑。
重启后,在绿色电池图标上点右键即可出现“双显卡切换”一项。高性能是独显,节省是集显。此时如果切换到集成显卡,任务栏会自动出现一个inter(R) graphics media……driver for mobile的驱动,如果切换到独立显卡,这个驱动图标就会消失。
我实验了几次都很正常,在独显时进入dxdiag,查看显示项名称为:ATI mobility … HD3400 series,估计内存为985M。如果切换为独显,就是另外一个显卡的信息了。

OK,显卡可以成功切换了,但是现在玩游戏不能全屏。我用的是下面的方法:
点开始菜单,在运行中输入regedit调处注册表,然后一次进入\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\GraphicsDrivers\\Configuration\下面可能有一个或多个内容,全部修改。以此进入每个内容的00—00,右边有一项Scaling,双击修改,在十六进制模式中修改为3,确定即可。然后重启电脑。
修改完毕后进入游戏时就会自动全屏了。
到此为止就可以进行双显卡切换并且玩游戏时可以正常全屏了,希望各位玩得愉快。 

posted @ 2010-10-30 11:55 fredxiong 阅读(6395) 评论(0) 编辑

2010年5月17日

1、使用Sp_executeSql执行SQL,用输出参数获得其变量

    declare @val varchar(100)
    
declare @Sql nvarchar(4000)
    
set @Sql = 'Set @val=5' 
    
exec Sp_executeSql @Sql, N'@val varchar(100) output',@val output
    
select @val as Value

 其中@Sql字符串,必须为 ntext/nchar/nvarchar三种类型中的一种,否则会出错

(以下摘自CSDN)

 2、在存储过程中使用RaisError,传回错误讯息

  IF @@Error<>0 

  RaisError '更新数据时错误',16,1

  return

 如果执行间段错误,傳回使用者自訂的錯誤訊息,並設定系統旗標,記錄曾發生過錯誤。

VB6用戶端获取错误信息:

On Error GoTo ErrDo 

.......

ErrDo:
    MsgBox "保存數據出錯: " & Err.Description   

3、 使用output参数
代码
IF OBJECT_ID ( 'Production.usp_GetList''P' ) IS NOT NULL 
    
DROP PROCEDURE Production.usp_GetList;
GO
CREATE PROCEDURE Production.usp_GetList @product varchar(40
    , @maxprice money 
    , @compareprice money OUTPUT
    , @listprice money OUT
AS
    
SELECT p.name AS Product, p.ListPrice AS 'List Price'
    
FROM Production.Product p
    
JOIN Production.ProductSubcategory s 
      
ON p.ProductSubcategoryID = s.ProductSubcategoryID
    
WHERE s.name LIKE @product AND p.ListPrice < @maxprice;
-- Populate the output variable @listprice.
SET @listprice = (SELECT MAX(p.ListPrice)
        
FROM Production.Product p
        
JOIN  Production.ProductSubcategory s 
          
ON p.ProductSubcategoryID = s.ProductSubcategoryID
        
WHERE s.name LIKE @product AND p.ListPrice < @maxprice);
-- Populate the output variable @compareprice.
SET @compareprice = @maxprice;
GO

 

另一个存储过程调用的时候:

DECLARE @compareprice money, @cost money
EXECUTE Production.usp_GetList '%Bikes%', 700,
    @compareprice OUT,
    @cost OUTPUT
SELECT  @compareprice,@cost

4、创建一个临时表

#tempTable (userName nvarchar(50))
insert into #tempTable(userName)
exec GetUserName

select #tempTable

--用完之后要把临时表清空
drop table #tempTable

 

posted @ 2010-05-17 16:04 fredxiong 阅读(541) 评论(0) 编辑

2010年4月16日

1 合理的索引设计:
例:表record有620000行,试看在不同的索引下,下面几个SQL的运行情况:
语句A
SELECT count(*) FROM record
WHERE date between '19991201' and '19991214‘ and amount >2000

语句B
SELECT count(*) FROM record
WHERE date >'19990901' and place IN ('BJ','SH')

语句C
SELECT date,sum(amount) FROM record
group by date
1 在date上建有一个非聚集索引
A:(25秒)
B:(27秒)
C:(55秒)
分析:
date上有大量的重复值,在非聚集索引下,数据在物理上随机存放在数据页上,在范围查找时,必须执行一次表扫描才能找到这一范围内的全部行。
2 在date上的一个聚集索引
A:(14秒)
B:(14秒)
C:(28秒)
分析:
在聚集索引下,数据在物理上按顺序在数据页上,重复值也排列在一起,因而在范围查找时,可以先找到这个范围的起末点,且只在这个范围内扫描数据页,避免了大范围扫描,提高了查询速度。
3 在place,date,amount上的组合索引
A:(26秒)
C:(27秒)
B:(11秒)
分析:
这是一个不很合理的组合索引,因为它的前导列是place,第一和第三条SQL没有引用place,因此也没有利用上索引;第二个SQL使用了place,且引用的所有列都包含在组合索引中,形成了索引覆盖,所以它的速度是非常快的。
4 在date,amount,place上的组合索引
A: (3秒)
B:(12秒)
C:(3秒)
分析:
这是一个合理的组合索引。它将date作为前导列,使每个SQL都可以利用索引,并且在第一和第三个SQL中形成了索引覆盖,因而性能达到了最优。

总结:

1 缺省情况下建立的索引是非聚集索引,但有时它并不是最佳的;合理的索引设计要建立在对各种查询的分析和预测上。一般来说:
有大量重复值、且经常有范围查询(between, >,<,>=,<=)和order by、group by发生的列,考虑建立聚集索引;
经常同时存取多列,且每列都含有重复值可考虑建立组合索引;在条件表达式中经常用到的不同值较多的列上建立检索,在不同值少的列上不要建立索引。比如在雇员 表的“性别”列上只有“男”与“女”两个不同值,因此就无必要建立索引。如果建立索引不但不会提高查询效率,反而会严重降低更新速度。
组合索引要尽量使关键查询形成索引覆盖,其前导列一定是使用最频繁的列。

2 避免使用不兼容的数据类型:
例如float和INt、char和varchar、bINary和varbINary是不兼容的。数据类型的不兼容可能使优化器无法执行一些本来可以进行的优化操作。例如:
SELECT name FROM employee WHERE salary > 60000
在这条语句中,如salary字段是money型的,则优化器很难对其进行优化,因为60000是个整型数。我们应当在编程时将整型转化成为钱币型,而不要等到运行时转化。

3 IS NULL 与IS NOT NULL:
不能用null作索引,任何包含null值的列都将不会被包含在索引中。即使索引有多列这样的情况下,只要这些列中有一列含有null,该列就会从索引中排除。也就是说如果某列存在空值,即使对该列建索引也不会提高性能。任何在WHERE子句中使用is null或is not null的语句优化器是不允许使用索引的。

5 IN、比CHARINDEX快,CHARINDEX会使索引失效:

如下面的例子十万条记录,用IN比CHARINDE快四倍

select * from moa_modatanew where ','+WO+',' in ( ',1280002863,',',1280002865,')
select * from moa_modatanew where ','+CAST(iid AS VARCHAR(10))+',' in ( ',12,',',13,')

select * from moa_modatanew where CHARINDEX(','+WO+',' , ',1280002863,1280002865,')>0
select * from moa_modatanew where CHARINDEX(','+CAST(IID AS VARCHAR(10))+',' , ',12,13,')>0


6 避免或简化排序:
应当简化或避免对大型表进行重复的排序。当能够利用索引自动以适当的次序产生输出时,优化器就避免了排序的步骤。以下是一些影响因素:
索引中不包括一个或几个待排序的列;
group by或order by子句中列的次序与索引的次序不一样;
排序的列来自不同的表。
为了避免不必要的排序,就要正确地增建索引,合理地合并数据库表(尽管有时可能影响表的规范化,但相对于效率的提高是值得的)。如果排序不可避免,那么应当试图简化它,如缩小排序的列的范围等。

7 消除对大型表行数据的顺序存取:
在 嵌套查询中,对表的顺序存取对查询效率可能产生致命的影响。比如采用顺序存取策略,一个嵌套3层的查询,如果每层都查询1000行,那么这个查询就要查询 10亿行数据。避免这种情况的主要方法就是对连接的列进行索引。例如,两个表:学生表(学号、姓名、年龄)和选课表(学号、课程号、成绩)。如果两个表要做连接,就要在“学号”这个连接字段上建立索引。
还可以使用并集来避免顺序存取。尽管在所有的检查列上都有索引,但某些形式的WHERE子句强迫优化器使用顺序存取。下面的查询将强迫对orders表执行顺序操作:
SELECT * FROM orders WHERE (customer_num=104 AND order_num>1001) OR order_num=1008
虽然在customer_num和order_num上建有索引,但是在上面的语句中优化器还是使用顺序存取路径扫描整个表。因为这个语句要检索的是分离的行的集合,所以应该改为如下语句:
SELECT * FROM orders WHERE customer_num=104 AND order_num>1001
UNION
SELECT * FROM orders WHERE order_num=1008
这样就能利用索引路径处理查询。

8 避免相关子查询:
一个列的标签同时在主查询和WHERE子句中的查询中出现,那么很可能当主查询中的列值改变之后,子查询必须重新查询一次。查询嵌套层次越多,效率越低,因此应当尽量避免子查询。如果子查询不可避免,那么要在子查询中过滤掉尽可能多的行。

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

 

SELECT * FROM customer WHERE zipcode LIKE “98_ _ _”
即使在zipcode字段上建立了索引,在这种情况下也还是采用顺序扫描的方式。如果把语句改为

SELECT * FROM customer WHERE zipcode >=“98000”,在执行查询时就会利用索引来查询,显然会大大提高速度。
另外,还要避免非开始的子串。例如语句:SELECT * FROM customer WHERE zipcode[2,3] >“80”,在WHERE子句中采用了非开始子串,因而这个语句也不会使用索引。

10 不充份的连接条件:
例:表card有7896行,在card_no上有一个非聚集索引,表account有191122行,在account_no上有一个非聚集索引,试看在不同的表连接条件下,两个SQL的执行情况:
SELECT sum(a.amount) FROM account a,card b WHERE a.card_no = b.card_no
(20秒)
将SQL改为:
SELECT sum(a.amount) FROM account a,card b WHERE a.card_no = b.card_no and a.account_no=b.account_no
(&lt; 1秒)
分析:
在第一个连接条件下,最佳查询方案是将account作外层表,card作内层表,利用card上的索引,其I/O次数可由以下公式估算为:
外层表account上的22541页+(外层表account的191122行*内层表card上对应外层表第一行所要查找的3页)=595907次I/O
在第二个连接条件下,最佳查询方案是将card作外层表,account作内层表,利用account上的索引,其I/O次数可由以下公式估算为:
外层表card上的1944页+(外层表card的7896行*内层表account上对应外层表每一行所要查找的4页)= 33528次I/O
可见,只有充份的连接条件,真正的最佳方案才会被执行。
多表操作在被实际执行前,查询优化器会根据连接条件,列出几组可能的连接方案并从中找出系统开销最小的最佳方案。连接条件要充份考虑带有索引的表、行数多的表;内外表的选择可由公式:外层表中的匹配行数*内层表中每一次查找的次数确定,乘积最小为最佳方案。
不可优化的WHERE子句
例1
下列SQL条件语句中的列都建有恰当的索引,但执行速度却非常慢:
SELECT * FROM record WHERE substrINg(card_no,1,4)='5378'
(13秒)
SELECT * FROM record WHERE amount/30&lt; 1000
(11秒)
SELECT * FROM record WHERE convert(char(10),date,112)='19991201'
(10秒)
分析:
WHERE子句中对列的任何操作结果都是在SQL运行时逐列计算得到的,因此它不得不进行表搜索,而没有使用该列上面的索引;如果这些结果在查询编译时就能得到,那么就可以被SQL优化器优化,使用索引,避免表搜索,因此将SQL重写成下面这样:
SELECT * FROM record WHERE card_no like '5378%'
(&lt; 1秒)
SELECT * FROM record WHERE amount&lt; 1000*30
(&lt; 1秒)
SELECT * FROM record WHERE date= '1999/12/01'
(&lt; 1秒)

11 存储过程中,采用临时表优化查询:

1.从parven表中按vendor_num的次序读数据:
SELECT part_num,vendor_num,price FROM parven ORDER BY vendor_num
INTO temp pv_by_vn
这个语句顺序读parven(50页),写一个临时表(50页),并排序。假定排序的开销为200页,总共是300页。
2.把临时表和vendor表连接,把结果输出到一个临时表,并按part_num排序:
SELECT pv_by_vn,* vendor.vendor_num FROM pv_by_vn,vendor
WHERE pv_by_vn.vendor_num=vendor.vendor_num
ORDER BY pv_by_vn.part_num
INTO TMP pvvn_by_pn
DROP TABLE pv_by_vn
这 个查询读取pv_by_vn(50页),它通过索引存取vendor表1.5万次,但由于按vendor_num次序排列,实际上只是通过索引顺序地读 vendor表(40+2=42页),输出的表每页约95行,共160页。写并存取这些页引发5*160=800次的读写,索引共读写892页。
3.把输出和part连接得到最后的结果:
SELECT pvvn_by_pn.*,part.part_desc FROM pvvn_by_pn,part
WHERE pvvn_by_pn.part_num=part.part_num
DROP TABLE pvvn_by_pn
这样,查询顺序地读pvvn_by_pn(160页),通过索引读part表1.5万次,由于建有索引,所以实际上进行1772次磁盘读写,优化比例为30∶1。

posted @ 2010-04-16 11:50 fredxiong 阅读(401) 评论(0) 编辑
 

一、索引的概念
        索引就是加快检索表中数据的方法。数据库的索引类似于书籍的索引。在书籍中,索引允许用户不必翻阅完整个书就能迅速地找到所需要的信息。在数据库中,索引也允许数据库程序迅速地找到表中的数据,而不必扫描整个数据库。

二、索引的特点
    1.索引可以加快数据库的检索速度
    2.索引降低了数据库插入、修改、删除等维护任务的速度
    3.索引创建在表上,不能创建在视图上
    4.索引既可以直接创建,也可以间接创建
    5.可以在优化隐藏中,使用索引
    6.使用查询处理器执行SQL语句,在一个表上,一次只能使用一个索引
    7.其他

三、索引的优点
    1.创建唯一性索引,保证数据库表中每一行数据的唯一性
    2.大大加快数据的检索速度,这也是创建索引的最主要的原因
    3.加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
    4.在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
    5.通过使用索引,可以在查询的过程中使用优化隐藏器,提高系统的性能。

四、索引的缺点
    1.创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加
    2.索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大
    3.当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度

五、索引分类

  1.聚簇索引和非聚簇索引(聚集索引,非聚集索引)

  聚集索引:该索引中键值的逻辑顺序决定了表中数据行的物理顺序。如果对从表中检索的数据进行排序时,

    经常要用到某一 列,则可以将该表在该列上聚集(物理排序),避免每次查询该列时都进行排序,从而节省成本
    CREATE CLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn) WITH
    ALLOW_DUP_ROW(允许有重复记录的聚簇索引)
    非聚簇索引:物理存储不按照索引排序

  CREATE UNCLUSTERED INDEX mycolumn_cindex ON mytable(mycolumn) 
    2.直接创建索引和间接创建索引
    直接创建索引: CREATE INDEX mycolumn_index ON mytable (myclumn)
    间接创建索引:定义主键约束或者唯一性键约束,可以间接创建索引 
    3.普通索引和唯一性索引
    普通索引:CREATE INDEX mycolumn_index ON mytable (myclumn)
    唯一性索引:保证在索引列中的全部数据是唯一的,对聚簇索引和非聚簇索引都可以使用
    CREATE UNIQUE COUSTERED INDEX myclumn_cindex ON mytable(mycolumn)
    3.单个索引和复合索引
    单个索引:即非复合索引
    复合索引:又叫组合索引,在索引建立语句中同时包含多个字段名,最多16个字段
    CREATE INDEX name_index ON username(firstname,lastname)  

六、索引的使用
   1.当字段数据更新频率较低,查询使用频率较高并且存在大量重复值是建议使用聚簇索引
    2.经常同时存取多列,且每列都含有重复值可考虑建立组合索引
    3.复合索引的前导列一定好控制好,否则无法起到索引的效果。如果查询时前导列不在查询条件中则该复合索引不会被使用。前导列一定是使用最频繁的列
    4.多表操作在被实际执行前,查询优化器会根据连接条件,列出几组可能的连接方案并从中找出系统开销最小的最佳方案。连接条件要充份考虑带有索引的表、行数多的表;内外表的选择可由公式:外层表中的匹配行数*内层表中每一次查找的次数确定,乘积最小为最佳方案
    5.where子句中对列的任何操作结果都是在sql运行时逐列计算得到的,因此它不得不进行表搜索,而没有使用该列上面的索引;如果这些结果在查询编译时就能得到,那么就可以被sql优化器优化,使用索引,避免表搜索(例:select * from record where substring(card_no,1,4)=’5378’
&& select * from record where card_no like ’5378%’)任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边
    6.where条件中的’in’在逻辑上相当于’or’,所以语法分析器会将in ('0','1')转化为column='0' or column='1'来执行。我们期望它会根据每个or子句分别查找,再将结果相加,这样可以利用column上的索引;但实际上它却采用了"or策略",即先取出满足每个or子句的行,存入临时数据库的工作表中,再建立唯一索引以去掉重复行,最后从这个临时表中计算结果。因此,实际过程没有利用column上索引,并且完成时间还要受tempdb数据库性能的影响。in、or子句常会使用工作表,使索引失效;如果不产生大量重复值,可以考虑把子句拆开;拆开的子句中应该包含索引 
   

posted @ 2010-04-16 11:30 fredxiong 阅读(245) 评论(0) 编辑

2010年4月12日

作者:蒋勇 http://idoorsoft.51.net/

  在数据库的应用系统中,充分的利用数据库的后台服务端的功能可以可以简化客户端前台的工作,更可以降低网络的负荷,同时使整个系统设计更合理,便于维护移植和升级,后台计划任务作业在很多数据库应用中经常会用到,当然是配合存储过程使用。
  在SQL Server2000中,可以手动一步一步的在企业管理器中建立后台计划任务作业,但这样既麻烦也不便于发布,因此本文给出使用T-SQL脚本创建作业的方法。
  需要下面三个SQL Server2000 msdb系统库中的存储过程来完成作业的建立,在此之前请先开启数据库实例的SQLServerAgent服务,SQL Server安装后默认是没有启动该服务的。
  顺便说一句,SQL Server在2000版本中才有了明显的“实例”的概念,在7.0版中没有明确的实例,因此在SQL Server2000默认安装时创建了一个默认实例,这是为了和SQl Server 7.0兼容,如果你是默认方式创建的实例,则实例名为空。啥子?你不晓得啥子是“实例”?个人去找点资料看看,oracel、sybase都有实例和表空间,所以我叫SQL Server2000之前的SQL Server为桌面数据库。
  进入正题,步骤是“作业”-〉“作业调度”-〉“作业步骤”,具体如下:

1、使用sp_add_job 添加由 SQLServerAgent 服务执行的新作业。
2、使用sp_add_jobschedule创建作业调度。
3、使用sp_add_jobstep将一个步骤(操作)添加到作业中


  下面以在汽车客运站票务系统中的脚本为例给出实际例子,在看例子之前,请先看一下上面三个系统存储过程的帮助。在例子中使用了一个自定义的存储过程“tksp_bakdata”,它的功能是处理当日之前售票数据(只需知道是一个自定义存储过程就行了)。


例子1:每日0点30分处理售票数据

代码
use msdb
EXEC sp_add_job @job_name = 'tk_bakdata',
@enabled = 1,
@description = '每日00:30处理售票数据',
@start_step_id = 1,
@owner_login_name = 'tkuser'
exec sp_add_jobserver @job_name = 'tk_bakdata'
go

EXEC sp_add_jobschedule @job_name = 'tk_bakdata'
@name = 'Bakdata003000',
@freq_type = 4,
@freq_interval = 1,
@active_start_time = 003000
go

EXEC sp_add_jobstep @job_name = 'tk_bakdata',
@step_name = 'bakdata',
@subsystem = 'TSQL',
@command = 'EXEC tksp_bakdata '
@database_name='ticket'
go

 

例子2:每日SQLServer启动时处理售票数据,这样在每天需要关机的服务器中也能保证处理售票数据。

代码
use msdb
EXEC sp_add_job @job_name = 'tk_bakdata2',
@enabled = 1,
@description = '每日SQLServer启动时处理售票数据',
@start_step_id = 1,
@owner_login_name = 'tkuser'
exec sp_add_jobserver @job_name = 'tk_bakdata2'
go

EXEC sp_add_jobschedule @job_name = 'tk_bakdata2'
@name = 'BakdataStart',
@freq_type = 64
go

EXEC sp_add_jobstep @job_name = 'tk_bakdata2',
@step_name = 'BakdataStart',
@subsystem = 'TSQL',
@command = 'EXEC tksp_bakdata '
@database_name='ticket'
go

 

 

posted @ 2010-04-12 21:59 fredxiong 阅读(160) 评论(0) 编辑

2010年3月26日

摘要: 1.在sqlserver创建用户临时表和系统临时表的方法,及两者的区别?用户临时表:create table #xx(ID int, IDValues int)系统临时表:create table ##xx(ID int, IDValues int)区别:用户临时表只对创建这个表的用户的Session可见,对其他进程是不可见的.当创建它的进程消失时这个临时表就自动删除.系统临时表对整个SQL Se...阅读全文
posted @ 2010-03-26 18:53 fredxiong 阅读(139) 评论(0) 编辑

2010年3月23日

摘要: 在Html页面插入FLASH动画一、直接插入已设计好的Flash文件,代码如下:代码 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--><div><objectclassid='clsid:D27CDB6E-AE6D-11cf-96B8...阅读全文
posted @ 2010-03-23 19:24 fredxiong 阅读(200) 评论(0) 编辑

2010年3月16日

摘要: GridView的RowCommand事件,当CommandName不是gridview 默认的三种命令名时,对表格的操作需触发RowCommand事件UI代码:代码 Code highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/--><asp:GridViewID...阅读全文
posted @ 2010-03-16 15:37 fredxiong 阅读(627) 评论(2) 编辑

2010年3月12日

摘要: 一. 锁使用注意事项 如何避免死锁1使用事务时,尽量缩短事务的逻辑处理过程,及早提交或回滚事务;3设置死锁超时参数为合理范围,如:3分钟-10分种;超过时间,自动放弃本次操作,避免进程悬挂;3所有的SP都要有错误处理(通过@@error)4一般不要修改SQL SERVER事务的默认级别。不推荐强行加锁 二. 几个有关加锁的例子代码Code highlighting produced by Acti...阅读全文
posted @ 2010-03-12 20:08 fredxiong 阅读(99) 评论(0) 编辑