Delphi 如何获取Access.MDB文件中存储的表的记录数?
我需要打开Delphi 如何获取Access.MDB文件中存储的表的记录数?,delphi,ms-access,database-schema,delphi-xe5,Delphi,Ms Access,Database Schema,Delphi Xe5,我需要打开tToTable之前的RcordCount。所以我运行这个查询: ADOQuery1.SQL.Text := ‘SELECT Count(*) AS Record_Count FROM Table1’; ADOQuery1.Open; 但是,对于一个包含500多万条记录的表,在我的PC上运行9.7秒(平均10次)。这一次似乎比不上触摸如此大小的表,但我认为这种数据应该存储在.mdb文件的某个地方。有没有其他方法可以直接从文件中获取表的RecordCount? 我使用的是Delphi
tToTable
之前的RcordCount
。所以我运行这个查询:
ADOQuery1.SQL.Text := ‘SELECT Count(*) AS Record_Count FROM Table1’;
ADOQuery1.Open;
但是,对于一个包含500多万条记录的表,在我的PC上运行9.7秒(平均10次)。这一次似乎比不上触摸如此大小的表,但我认为这种数据应该存储在.mdb文件的某个地方。有没有其他方法可以直接从文件中获取表的RecordCount?
我使用的是Delphi XE-5,文件是Microsoft Access 2003格式。否,选择计数(*)
是唯一正确的方法
但是:对于这个查询,几乎10秒的时间非常慢,尤其是在本地PC上
表是否有主键?如果是,它是什么数据类型
我用自动编号主键创建了一个简单的表,并插入了500万条记录。SELECT COUNT(*)FROM tBig
执行时间不到1/10秒。否,SELECT COUNT(*)是唯一正确的方法
但是:对于这个查询,几乎10秒的时间非常慢,尤其是在本地PC上
表是否有主键?如果是,它是什么数据类型
我用自动编号主键创建了一个简单的表,并插入了500万条记录。
从tBig中选择COUNT(*)执行不到1/10秒。我同意Andre451。我要说的另一件事是,您应该在Count语句中指定字段,而不是使用*
从tBig中选择计数(主键)代码>就可以了。我同意安德烈的观点。我要说的另一件事是,您应该在Count语句中指定字段,而不是使用*
从tBig中选择计数(主键)代码>就可以了。好吧,我再搜索了一点,找到了它。您可以直接从架构中读取表的记录数:
function ReadRecordCountFromSchema(const Connection: TADOConnection;
const TableName: string): Integer;
var
CardinalityField,
NameField: TField;
DataSet: TADODataSet;
begin
DataSet := TADODataSet.Create(nil);
Result := -1;
try
Connection.OpenSchema(siStatistics, EmptyParam, EmptyParam, DataSet);
CardinalityField := DataSet.FieldByName('CARDINALITY'); { do not localize }
NameField := DataSet.FieldByName('TABLE_NAME'); { do not localize }
while not DataSet.EOF do
begin
if CompareText(NameField.AsString, TableName) = 0 then
begin
Result := CardinalityField.AsInteger;
Break;
end;
DataSet.Next;
end;
finally
DataSet.Free;
end;
end;
实际上,TADOConnection.GetTableNames
给了我这个想法
编辑:
正如Andre451所提到的,最好将TableName
传递给OpenSchema
作为限制:
function ReadRecordCountFromSchema(const Connection: TADOConnection;
const TableName: string): Integer;
var
DataSet: TADODataSet;
begin
DataSet := TADODataSet.Create(nil);
Result := -1;
try
Connection.OpenSchema(siStatistics,
VarArrayOf([Unassigned, Unassigned, TableName]),
EmptyParam, DataSet);
if DataSet.RecordCount > 0 then
Result := DataSet.FieldByName('CARDINALITY').AsInteger;
finally
DataSet.Free;
end;
end;
嗯,我又找了一点,找到了。您可以直接从架构中读取表的记录数:
function ReadRecordCountFromSchema(const Connection: TADOConnection;
const TableName: string): Integer;
var
CardinalityField,
NameField: TField;
DataSet: TADODataSet;
begin
DataSet := TADODataSet.Create(nil);
Result := -1;
try
Connection.OpenSchema(siStatistics, EmptyParam, EmptyParam, DataSet);
CardinalityField := DataSet.FieldByName('CARDINALITY'); { do not localize }
NameField := DataSet.FieldByName('TABLE_NAME'); { do not localize }
while not DataSet.EOF do
begin
if CompareText(NameField.AsString, TableName) = 0 then
begin
Result := CardinalityField.AsInteger;
Break;
end;
DataSet.Next;
end;
finally
DataSet.Free;
end;
end;
实际上,TADOConnection.GetTableNames
给了我这个想法
编辑:
正如Andre451所提到的,最好将TableName
传递给OpenSchema
作为限制:
function ReadRecordCountFromSchema(const Connection: TADOConnection;
const TableName: string): Integer;
var
DataSet: TADODataSet;
begin
DataSet := TADODataSet.Create(nil);
Result := -1;
try
Connection.OpenSchema(siStatistics,
VarArrayOf([Unassigned, Unassigned, TableName]),
EmptyParam, DataSet);
if DataSet.RecordCount > 0 then
Result := DataSet.FieldByName('CARDINALITY').AsInteger;
finally
DataSet.Free;
end;
end;
可能有这个吗?但我想您必须通过OLE自动化才能访问这样的属性。如果您需要多个表的属性,则速度可能会更快….?可能有任何与此相关的信息吗?但我想您必须通过OLE自动化才能访问这样的属性。如果您需要多个表的属性,速度可能会更快…?不,它没有主键,它是8个双键和3个字符串,大小约为1.2GB。请阅读我的答案,看看是否正确。@saastn:这就是问题所在。如果没有主键,则必须读取整个表以统计记录。使用主键时,只读取此索引,速度快了几个数量级。不,它没有主键,它有8个双键和3个字符串,大小约为1.2GB。请阅读我的答案,看看是否正确。@saastn:这就是问题所在。如果没有主键,则必须读取整个表以统计记录。使用主键时,只读取这个索引,速度快了好几个数量级。它没有,但我用双字段替换了*,这使得查询速度更慢!最好使用选择计数(*)
。如果有PK,两者都是等价的(都读取PK索引),但是如果PK是复合的,你会怎么做?计算没有PK(或唯一索引)的字段比计算(*)慢。同意。它需要在索引字段上,或者查询必须“扫描”表,这太慢了!嗯,它没有,但我用双字段替换了*,这使得查询速度更慢!最好使用选择计数(*)
。如果有PK,两者都是等价的(都读取PK索引),但是如果PK是复合的,你会怎么做?计算没有PK(或唯一索引)的字段比计算(*)慢。同意。它需要在索引字段上,或者查询必须“扫描”表,这太慢了!有意思,我没听说过这个。但这只有在表上有索引时才有效,因此它也会读取索引,记录的数量不会神奇地存储在数据库中。使用索引,SELECT COUNT(*)
也应该很快。它不需要是主键,我错了。顺便说一句。您应该能够在OpenSchema
中指定表名,这样就不必对结果进行循环。请参阅@Andre451我更改了代码以防止循环。但是,您所说的关于索引的内容只有在您将siIndexes
作为Schema
参数传递时才是正确的,我检查了siStatistics
中一个没有索引字段的表,它工作了。我不确定这个方法是否100%可靠。尝试在Access中打开表并添加记录。当表格在Access中打开时,试着看看你的Delphi应用程序报告有多少条记录…@kobik好吧,我在我的电脑上检查了一下,它成功了。我试着在另一个框中检查它,它说“提供商不支持它”。回到我的电脑上,我检查了一些其他场景,有时数据集是空的。。。所以,是的,既不可靠也不便携。有趣的是,我没听说过这个。但这只有在表上有索引时才有效,因此它也会读取索引,记录的数量不会神奇地存储在数据库中。使用索引,SELECT COUNT(*)
也应该很快。它不需要是主键,我错了。顺便说一句。您应该能够在OpenSchema
中指定表名,以便