Foxpro2.5的数据库记录超过39万条,但是速度变的奇慢,一夜之间还作不了一个统计,如何是好??快救命啊!!!

时间:2022-07-16 23:21:32


我们单位的医疗系统,存放病人的药物清单记录,用了近三年了。。
记录超过三十九万条而已,但是检索速度奇慢,有关这个数据据的新增和保存程序都变的奇慢,如何是好???!!!!!!!!!!

最近我要作一个关于清单的统计查询,
在模拟服务器上调试好了。。。测试几天的数据还可以检索,,,,
要半个小时,,,

然后把程序放入真正的服务器,作了一个晚上还没有出来。。。。。

怎么怎么慢。。。。???
我用FOX直接操作这个数据库表,
在多条件的Locate 时,,非常的慢,如何解决呢???
急啊???、、


请大侠告诉我如何检索一个FOxpro数据库比较快,,在数据比较多的时候???

Seek语句支持多字段,多条件And 吗???


谢谢了。。。。

23 个解决方案

#1


根据你的关键字段建索引,用scan处理,可能会比较快,能够分组统计,39万记录不算多,要想办法优化好数据是最关键的。
建索引可以field1+field2...
-----------------------------
我流落在凄凉的世界里-孤苦伶仃
我过着动荡无助的生活-四处漂泊
我在死亡线上苦苦挣扎-度日如年

#2


定位是不是用SEEK??

但是怎么不管用啊??

单个字段组合的IDx,就可以SEEk,,

但是多个字段field1+field2...  的IDx,SEEk不出来,,,
怎么回事,

哪里短路了????

#3


看看你的代码,是不是其中加的循环嵌套太多了,把代码优化一下.

#4


只能在索引过的表中使用 seek 命令,并且只能搜索索引关键字。
你进行多个关键字索引时,也只能对第一个关键字进行 seek命令操作。

#5


先改变一下理念:将数据分解到每一年一个表

然后用fj_jiangqi(强盗)的方法对关健字进行索引

另外,可以用SELE语句,可能效率要高些

#6


要查找或者统计的字段索引,会相应提高数度。

#7


你为什么要用LOCATE,这个东西一点用都没有,全部用SEEK()来用,我作了一个系统几亿条,也就是几分钟,
如果没有自然灾难,几年都不会有问题,都是用*。DBF的

#8


SEEK()可以用一个复合索引,不过要在表中先作一个复合索引

#9


将几年的数据分开.
如果程序为自己开发,还是升级到vfp+sql server,不过数据太多还是分为几个表,速度会快很多.

#10


要不你把关键字段写出来和统计的项目,让我们一起分析,相信你可以得到想要的答案。以前我有做过300万条记录,很快就完成了。我想你的数据只要用正确的方法,速度一定会提高很多的。
-----------------------------
我流落在凄凉的世界里-孤苦伶仃
我过着动荡无助的生活-四处漂泊
我在死亡线上苦苦挣扎-度日如年

#11


还是把VFp的数据库升级到SQL吧,

#12


好象以前有一个类似的贴子,我也来参与解答过。
分年,分月保存数据,再运用索引技术,可以在查询速度上提高很快。
以前我做的那个医院管理系统,在七八年的数据中,要查询某住院病人的用药情况,不到一分钟就可以查出所有的结果。同样,统计全年全院各科室的各种费用的收入情况,查询时间也不过五六分钟时间。
不信你试试看。

#13


谢谢各位,,
升级的问题,暂时不太可能。。谢谢了。

但是我分了数据。。
一个的一个表,我作了。。。
还是要一个晚上才出来结果,,

不过算是进步了,没有分数据以前,一个晚上都出不来。。。
哈哈 。。

#14


一年的一个表,

我用的是LOcate函数。。。

估计用SEEK可能是非常快,,,

但是我碰到了问题了。。。。。。。。。。

我的问题前面也说了。。。
---是:
单个字段组合的IDx,就可以SEEk,,

但是多个字段field1+field2...  的IDx,SEEk不出来,,,
怎么回事,

哪里短路了????

cdx索引也也样,,
可能我的问题,是不怎么会用sEEk

。特别是复合字段时,,,
不像Locate ,用一个FOR字句就搞定了。。

#15


呵呵,FOXPRO是G级的数据库,我现在做的库动则都要三四百万条记录,统计起来也就一小会儿,分年分月处理确实是办法,但你那三十几万条还不到用这个的时候,明显是你的数据处理方式的问题.你不提出具体的情况,大家的解答都找不到北的,这么笼统的说没用,你可以把数据筛几条贴出来,然后说明情况,然后大家帮你研究.

#16


关键是索引。
你要把所有查询的条件都索引。
如果索引了,即使用LOCATE FOR 且用AND,系统也会用RUSHMORE优化的,与SEEK会一样快的。

#17


您的问题很容易解决的,增加索引就可以了.
如果是两个字段的索引应该这样做
Index on <fieldname1>+<fieldname2> to <indexname1>
然后您再SEEK看看,是不是速度可以加快N倍?

#18




谢谢各位!!!

那各位大哥就先教我弄明白一个问题!!!
那就是set order to后面跟着的那个东西,到底是数据库的字段名,还是数据库的索引文件名(是*.cdx文件名,还是*.idx文件名),还是索引设置里的TAG名呢???

#19


指定主控索引文件或标识的编号。nIndexNumber 指的是在 USE 或 SET INDEX 中列出索引文件的顺序号。首先按它们在 USE 或 SET INDEX 中出现的顺序为打开的 .IDX 文件编号。随后,按创建顺序为结构 .CDX 文件中的索引标识(如果存在的话)编号。最后,按创建顺序为所有打开的独立的 .CDX 文件中的索引标识编号。

#20


请参考:
---------------------------------------------------
指定表的主控索引文件或标识。

SET ORDER TO [nIndexNumber | IDXIndexFileName | [TAG] TagName 
   [OF CDXFileName] [IN nWorkArea | cTableAlias]
   [ASCENDING | DESCENDING]]
参数
nIndexNumber 
指定主控索引文件或标识的编号。nIndexNumber 指的是在 USE 或 SET INDEX 中列出索引文件的顺序号。首先按它们在 USE 或 SET INDEX 中出现的顺序为打开的 .IDX 文件编号。随后,按创建顺序为结构 .CDX 文件中的索引标识(如果存在的话)编号。最后,按创建顺序为所有打开的独立的 .CDX 文件中的索引标识编号。 
下面示例说明了不同索引文件类型和标识的编号方式(文件名只是为了说明问题,并不需要真正存在)。表 video.dbf 打开时带有三个索引 (title.idx, costs.cdx 和 rating.idx),使用下面命令将其在第一个工作区中打开: 

USE video INDEX title.idx, costs.cdx, rating.idx IN 1
video 表有一个结构复合索引文件(video.cdx),其中有两个索引标识(NUMBERSOLD 和 YEARSOLD)。打开 video 时,此结构 .CDX 文件自动打开。

由于 .IDX 文件首先被编号,因此发出命令 SET ORDER TO 1 将使 title.idx 成为主控索引,而发出 SET ORDER TO 2 则使 rating.idx 成为主控索引: 

SET ORDER TO 1
Controlling index: C:\FOX30\TITLE.IDX 
SET ORDER TO 2
Controlling index: C:\FOX30\RATING.IDX 
其次对 video.cdx 中的索引标识进行编号: 

SET ORDER TO 3
Controlling index: C:\FOX30\VIDEO.CDX  Tag: NUMBERSOLD 
SET ORDER TO 4
Controlling index: C:\FOX30\VIDEO.CDX  Tag: YEARSOLD 
独立文件 costs.cdx 中的索引标识最后被编号: 

SET ORDER TO 5
Controlling index: C:\FOX30\COSTS.CDX  Tag: RENTALCOST
SET ORDER TO 6
Controlling index: C:\FOX30\COSTS.CDX  Tag: BUYCOST
nIndexNumber 也可以是 0。如果发出 SET ORDER TO 0 命令,则所有索引文件仍保持打开,并且在增加、删除或修改记录时更新。但是,表中所有记录的显示和访问顺序是记录编号顺序而不是索引顺序。不带其他参数的 SET ORDER TO 命令与 SET ORDER TO 0 命令完全一样。 

如果 nIndexNumber 大于 .IDX 文件和 .CDX 文件的索引标识数,则 Visual FoxPro 产生错误信息。 

IDXIndexFileName 
指定作为主控索引文件的 .IDX 文件。 
[TAG] TagName [OF CDXFileName] 
指定 .CDX 文件中的一个标识作为主控索引标识。标识名可以来自结构 .CDX 文件或任何打开的独立 .CDX 文件。 
如果在各打开的独立 .CDX 文件中存在相同的标识名,应使用 OF CDXFileName 来指定包含此标识的 .CDX 文件。 

注意   如果 .IDX 文件和标识名重复,.IDX 文件优先。
IN nWorkArea | cTableAlias 
为在非当前选定工作区中打开的表指定主控索引文件或索引标识。nWorkArea 指定工作区编号,cTableAlias 指定表的别名。 
ASCENDING | DESCENDING 
以升序或降序显示或访问表记录。使用 ASCENDING 或 DESCENDING 不会改变索引文件或索引标识。 
备注
一个表可以同时打开多个索引文件。但是,只有一个单索引 (.IDX) 文件(主控索引文件)或一个来自复合索引 (.CDX) 文件的索引标识(主控标识)决定表中记录的显示和访问顺序。可用 SET ORDER 来指定主控索引文件或标识。有些命令(例如 SEEK)使用主控索引或标识来查找记录。

可以在 USE 命令中包含 INDEX 子句随表打开索引文件。如果一个表有相关的结构 .CDX 文件,这个文件会随着表的打开而自动打开。在一个表被打开以后,可以使用 SET INDEX 命令为这个表打开或关闭索引文件。

默认情况下,SET ORDER 为当前工作区中打开的表指定主控索引或主控标识。

#21


谢谢各位,终于学会了。

其实问题的关键是。
我操作的那个数据哭,ZYH住院好,  CYRQ住院日期,
ZYH住院好 是7位字符,但是原来的程序只填了,最左边的6位,然后有一个空格。(6+空格)

有个索引是ZYH住院好+CYRQ住院日期,

我拿了好多好多的数据来测这个索引,但是就是SEEK不出数据,弄的我都快跳楼了。。。
怀疑是自己的对SEEK的使用不对,,


哦。
后来发现原来,住院号后要加个空格,在加日期,才可以找到数据。了。

哈哈。

终于不用跳楼了。。。。

#22


那就快散分啊..

#23


还有,你原来的dbf文件中是不是有很我有删除标记的数据没有真正的删除,如果这些记录不再需要的话,可以用pack命令删除掉,这样能减少数据文件的大小

#1


根据你的关键字段建索引,用scan处理,可能会比较快,能够分组统计,39万记录不算多,要想办法优化好数据是最关键的。
建索引可以field1+field2...
-----------------------------
我流落在凄凉的世界里-孤苦伶仃
我过着动荡无助的生活-四处漂泊
我在死亡线上苦苦挣扎-度日如年

#2


定位是不是用SEEK??

但是怎么不管用啊??

单个字段组合的IDx,就可以SEEk,,

但是多个字段field1+field2...  的IDx,SEEk不出来,,,
怎么回事,

哪里短路了????

#3


看看你的代码,是不是其中加的循环嵌套太多了,把代码优化一下.

#4


只能在索引过的表中使用 seek 命令,并且只能搜索索引关键字。
你进行多个关键字索引时,也只能对第一个关键字进行 seek命令操作。

#5


先改变一下理念:将数据分解到每一年一个表

然后用fj_jiangqi(强盗)的方法对关健字进行索引

另外,可以用SELE语句,可能效率要高些

#6


要查找或者统计的字段索引,会相应提高数度。

#7


你为什么要用LOCATE,这个东西一点用都没有,全部用SEEK()来用,我作了一个系统几亿条,也就是几分钟,
如果没有自然灾难,几年都不会有问题,都是用*。DBF的

#8


SEEK()可以用一个复合索引,不过要在表中先作一个复合索引

#9


将几年的数据分开.
如果程序为自己开发,还是升级到vfp+sql server,不过数据太多还是分为几个表,速度会快很多.

#10


要不你把关键字段写出来和统计的项目,让我们一起分析,相信你可以得到想要的答案。以前我有做过300万条记录,很快就完成了。我想你的数据只要用正确的方法,速度一定会提高很多的。
-----------------------------
我流落在凄凉的世界里-孤苦伶仃
我过着动荡无助的生活-四处漂泊
我在死亡线上苦苦挣扎-度日如年

#11


还是把VFp的数据库升级到SQL吧,

#12


好象以前有一个类似的贴子,我也来参与解答过。
分年,分月保存数据,再运用索引技术,可以在查询速度上提高很快。
以前我做的那个医院管理系统,在七八年的数据中,要查询某住院病人的用药情况,不到一分钟就可以查出所有的结果。同样,统计全年全院各科室的各种费用的收入情况,查询时间也不过五六分钟时间。
不信你试试看。

#13


谢谢各位,,
升级的问题,暂时不太可能。。谢谢了。

但是我分了数据。。
一个的一个表,我作了。。。
还是要一个晚上才出来结果,,

不过算是进步了,没有分数据以前,一个晚上都出不来。。。
哈哈 。。

#14


一年的一个表,

我用的是LOcate函数。。。

估计用SEEK可能是非常快,,,

但是我碰到了问题了。。。。。。。。。。

我的问题前面也说了。。。
---是:
单个字段组合的IDx,就可以SEEk,,

但是多个字段field1+field2...  的IDx,SEEk不出来,,,
怎么回事,

哪里短路了????

cdx索引也也样,,
可能我的问题,是不怎么会用sEEk

。特别是复合字段时,,,
不像Locate ,用一个FOR字句就搞定了。。

#15


呵呵,FOXPRO是G级的数据库,我现在做的库动则都要三四百万条记录,统计起来也就一小会儿,分年分月处理确实是办法,但你那三十几万条还不到用这个的时候,明显是你的数据处理方式的问题.你不提出具体的情况,大家的解答都找不到北的,这么笼统的说没用,你可以把数据筛几条贴出来,然后说明情况,然后大家帮你研究.

#16


关键是索引。
你要把所有查询的条件都索引。
如果索引了,即使用LOCATE FOR 且用AND,系统也会用RUSHMORE优化的,与SEEK会一样快的。

#17


您的问题很容易解决的,增加索引就可以了.
如果是两个字段的索引应该这样做
Index on <fieldname1>+<fieldname2> to <indexname1>
然后您再SEEK看看,是不是速度可以加快N倍?

#18




谢谢各位!!!

那各位大哥就先教我弄明白一个问题!!!
那就是set order to后面跟着的那个东西,到底是数据库的字段名,还是数据库的索引文件名(是*.cdx文件名,还是*.idx文件名),还是索引设置里的TAG名呢???

#19


指定主控索引文件或标识的编号。nIndexNumber 指的是在 USE 或 SET INDEX 中列出索引文件的顺序号。首先按它们在 USE 或 SET INDEX 中出现的顺序为打开的 .IDX 文件编号。随后,按创建顺序为结构 .CDX 文件中的索引标识(如果存在的话)编号。最后,按创建顺序为所有打开的独立的 .CDX 文件中的索引标识编号。

#20


请参考:
---------------------------------------------------
指定表的主控索引文件或标识。

SET ORDER TO [nIndexNumber | IDXIndexFileName | [TAG] TagName 
   [OF CDXFileName] [IN nWorkArea | cTableAlias]
   [ASCENDING | DESCENDING]]
参数
nIndexNumber 
指定主控索引文件或标识的编号。nIndexNumber 指的是在 USE 或 SET INDEX 中列出索引文件的顺序号。首先按它们在 USE 或 SET INDEX 中出现的顺序为打开的 .IDX 文件编号。随后,按创建顺序为结构 .CDX 文件中的索引标识(如果存在的话)编号。最后,按创建顺序为所有打开的独立的 .CDX 文件中的索引标识编号。 
下面示例说明了不同索引文件类型和标识的编号方式(文件名只是为了说明问题,并不需要真正存在)。表 video.dbf 打开时带有三个索引 (title.idx, costs.cdx 和 rating.idx),使用下面命令将其在第一个工作区中打开: 

USE video INDEX title.idx, costs.cdx, rating.idx IN 1
video 表有一个结构复合索引文件(video.cdx),其中有两个索引标识(NUMBERSOLD 和 YEARSOLD)。打开 video 时,此结构 .CDX 文件自动打开。

由于 .IDX 文件首先被编号,因此发出命令 SET ORDER TO 1 将使 title.idx 成为主控索引,而发出 SET ORDER TO 2 则使 rating.idx 成为主控索引: 

SET ORDER TO 1
Controlling index: C:\FOX30\TITLE.IDX 
SET ORDER TO 2
Controlling index: C:\FOX30\RATING.IDX 
其次对 video.cdx 中的索引标识进行编号: 

SET ORDER TO 3
Controlling index: C:\FOX30\VIDEO.CDX  Tag: NUMBERSOLD 
SET ORDER TO 4
Controlling index: C:\FOX30\VIDEO.CDX  Tag: YEARSOLD 
独立文件 costs.cdx 中的索引标识最后被编号: 

SET ORDER TO 5
Controlling index: C:\FOX30\COSTS.CDX  Tag: RENTALCOST
SET ORDER TO 6
Controlling index: C:\FOX30\COSTS.CDX  Tag: BUYCOST
nIndexNumber 也可以是 0。如果发出 SET ORDER TO 0 命令,则所有索引文件仍保持打开,并且在增加、删除或修改记录时更新。但是,表中所有记录的显示和访问顺序是记录编号顺序而不是索引顺序。不带其他参数的 SET ORDER TO 命令与 SET ORDER TO 0 命令完全一样。 

如果 nIndexNumber 大于 .IDX 文件和 .CDX 文件的索引标识数,则 Visual FoxPro 产生错误信息。 

IDXIndexFileName 
指定作为主控索引文件的 .IDX 文件。 
[TAG] TagName [OF CDXFileName] 
指定 .CDX 文件中的一个标识作为主控索引标识。标识名可以来自结构 .CDX 文件或任何打开的独立 .CDX 文件。 
如果在各打开的独立 .CDX 文件中存在相同的标识名,应使用 OF CDXFileName 来指定包含此标识的 .CDX 文件。 

注意   如果 .IDX 文件和标识名重复,.IDX 文件优先。
IN nWorkArea | cTableAlias 
为在非当前选定工作区中打开的表指定主控索引文件或索引标识。nWorkArea 指定工作区编号,cTableAlias 指定表的别名。 
ASCENDING | DESCENDING 
以升序或降序显示或访问表记录。使用 ASCENDING 或 DESCENDING 不会改变索引文件或索引标识。 
备注
一个表可以同时打开多个索引文件。但是,只有一个单索引 (.IDX) 文件(主控索引文件)或一个来自复合索引 (.CDX) 文件的索引标识(主控标识)决定表中记录的显示和访问顺序。可用 SET ORDER 来指定主控索引文件或标识。有些命令(例如 SEEK)使用主控索引或标识来查找记录。

可以在 USE 命令中包含 INDEX 子句随表打开索引文件。如果一个表有相关的结构 .CDX 文件,这个文件会随着表的打开而自动打开。在一个表被打开以后,可以使用 SET INDEX 命令为这个表打开或关闭索引文件。

默认情况下,SET ORDER 为当前工作区中打开的表指定主控索引或主控标识。

#21


谢谢各位,终于学会了。

其实问题的关键是。
我操作的那个数据哭,ZYH住院好,  CYRQ住院日期,
ZYH住院好 是7位字符,但是原来的程序只填了,最左边的6位,然后有一个空格。(6+空格)

有个索引是ZYH住院好+CYRQ住院日期,

我拿了好多好多的数据来测这个索引,但是就是SEEK不出数据,弄的我都快跳楼了。。。
怀疑是自己的对SEEK的使用不对,,


哦。
后来发现原来,住院号后要加个空格,在加日期,才可以找到数据。了。

哈哈。

终于不用跳楼了。。。。

#22


那就快散分啊..

#23


还有,你原来的dbf文件中是不是有很我有删除标记的数据没有真正的删除,如果这些记录不再需要的话,可以用pack命令删除掉,这样能减少数据文件的大小