【发布时间】:2015-10-17 21:29:36
【问题描述】:
我正在开发一个界面,以在 WinForm 应用程序中显示 DBF 文件中的数据。 我开始使用 OdbcConnection。尽管它有效,但由于 Visual FoxPro 驱动程序的某些限制(不支持子查询),我打开了使用 OLEDB(VFPOLEDB)。现在我能够运行复杂的查询,但出现了必须解决的新困难。问题是这些查询太慢了。比预期慢 100 倍。
下面是演示代码。 有一个 DBF 表“PROD”。索引字段 PRICE_N 用于查询的 Where 子句。该表位于运行应用程序的同一台 PC 上。如您所见,通过 ODBC(Microsoft Visual FoxPro 驱动程序)和 OLEDB(VFPOLEDB)运行查询所花费的时间差别很大。
TimeSpan timeSpanODBC;
DateTime timeODBC = DateTime.Now;
OdbcConnection odbcConnection = new OdbcConnection(@"Driver={Microsoft Visual FoxPro Driver};SourceType=DBF;SourceDB=C:\Users\Vakshul\Documents\dbfs;Exclusive=No;Collate=Machine;NULL=NO;DELETED=NO;BACKGROUNDFETCH=NO;");
odbcConnection.Open();
OdbcCommand odbcCommand = new OdbcCommand("SELECT utk_ved FROM prod WHERE (price_n='641857')", odbcConnection);
odbcCommand.ExecuteScalar();
timeSpanODBC = DateTime.Now - timeODBC;
double timeOdbcEqual = timeSpanODBC.TotalMilliseconds;
System.Console.WriteLine("Time spent via ODBC(milliseconds) using '=' to compare - {0}", timeOdbcEqual.ToString());
timeODBC = DateTime.Now;
odbcCommand = new OdbcCommand("SELECT utk_ved FROM prod WHERE (price_n like'641857')", odbcConnection);
odbcCommand.ExecuteScalar();
timeSpanODBC = DateTime.Now - timeODBC;
double timeOdbcLike = timeSpanODBC.TotalMilliseconds;
System.Console.WriteLine("Time spent via ODBC(milliseconds) using 'Like' to compare - {0}", timeOdbcLike.ToString());
TimeSpan timeSpanOLEDB;
DateTime timeOLEDB = DateTime.Now;
OleDbConnection oleDbCon = new OleDbConnection(@"Provider=VFPOLEDB.1;Data Source=C:\Users\Vakshul\Documents\dbfs;Collating Sequence=MACHINE;Mode=Read");
oleDbCon.Open();
OleDbCommand oleDbcommand = new OleDbCommand("SELECT utk_ved FROM prod WHERE (price_n = '641857')", oleDbCon);
oleDbcommand.ExecuteScalar();
timeSpanOLEDB = DateTime.Now - timeOLEDB;
double timeOLEDBEqual = timeSpanOLEDB.TotalMilliseconds;
System.Console.WriteLine("Time spent via OLEDB(milliseconds) using '=' to compare - {0}", timeOLEDBEqual.ToString());
timeOLEDB = DateTime.Now;
oleDbcommand = new OleDbCommand("SELECT utk_ved FROM prod WHERE (price_n like '641857')", oleDbCon);
oleDbcommand.ExecuteScalar();
timeSpanOLEDB = DateTime.Now - timeOLEDB;
double timeOLEDLike = timeSpanOLEDB.TotalMilliseconds;
System.Console.WriteLine("Time spent via OLEDB(milliseconds) using 'Like' to compare - {0}", timeOLEDLike.ToString());
System.Console.WriteLine("ODBC is faster than OLEDB {0} times using '=' to compare", Math.Round(timeOLEDBEqual / timeOdbcEqual, 0));
System.Console.WriteLine("ODBC is faster than OLEDB {0} times using 'Like' to compare", Math.Round(timeOLEDBEqual / timeOdbcEqual, 0));
控制台,第一次运行后:
Time spent via ODBC(milliseconds) using '=' to compare - 5,0006
Time spent via ODBC(milliseconds) using 'Like' to compare - 3,5005
Time spent via OLEDB(milliseconds) using '=' to compare - 1630,207
Time spent via OLEDB(milliseconds) using 'Like' to compare - 1755,2228
ODBC is faster than OLEDB 326 times using '=' to compare
ODBC is faster than OLEDB 326 times using 'Like' to compare
Console, after the second run:
Time spent via ODBC(milliseconds) using '=' to compare - 4,5006
Time spent via ODBC(milliseconds) using 'Like' to compare - 4,5005
Time spent via OLEDB(milliseconds) using '=' to compare - 1526,1938
Time spent via OLEDB(milliseconds) using 'Like' to compare - 1595,2026
ODBC is faster than OLEDB 339 times using '=' to compare
ODBC is faster than OLEDB 339 times using 'Like' to compare
Console, after the third run:
Time spent via ODBC(milliseconds) using '=' to compare - 4,0005
Time spent via ODBC(milliseconds) using 'Like' to compare - 3,0004
Time spent via OLEDB(milliseconds) using '=' to compare - 1449,184
Time spent via OLEDB(milliseconds) using 'Like' to compare - 1451,1843
ODBC is faster than OLEDB 362 times using '=' to compare
ODBC is faster than OLEDB 362 times using 'Like' to compare
Console, after the fourth run:
Time spent via ODBC(milliseconds) using '=' to compare - 3,5004
Time spent via ODBC(milliseconds) using 'Like' to compare - 4,5006
Time spent via OLEDB(milliseconds) using '=' to compare - 1475,6874
Time spent via OLEDB(milliseconds) using 'Like' to compare - 1621,2059
ODBC is faster than OLEDB 422 times using '=' to compare
ODBC is faster than OLEDB 422 times using 'Like' to compare
在此示例中,索引字段 PRICE_N 包含在查询的 Where 子句中。 我还测试了相同的查询,包括 Where 子句中的非索引字段而不是索引字段。结果是相同的 ~ 1400 – 1600 毫秒。 我的印象是,在 OLEDB(VFPOLEDB) 的情况下不使用索引。 我对结果不满意,我需要使用索引。
如果有人有任何建议,我将非常感激。
【问题讨论】:
-
你见过this article吗?
-
谢谢,@stuartd。我以前没看过,所以我仔细阅读了。
-
谢谢,@stuartd。我以前没看过,所以我仔细阅读了它。我尝试使用 TABLEVALIDATE=0 但无济于事。什么也没有变。速度如此之低,以至于很难相信。我猜没有使用索引。但为什么会这样?我什至部署了一个虚拟机,在那里安装了所有需要的软件,但结果相同:(
-
那么列上定义了 CDX 索引吗?你见过this question吗?
-
另外,您说您正在使用 VFPOLEDB 驱动程序,因为本机驱动程序不支持子查询:我记得当我是 VFP 开发人员时,这是一个痛苦的背影(当年份编号有里面有很多“九”)虽然这很痛苦,但可以通过创造性地使用外连接来解决。你真的需要子查询吗? (我已经用
Visual-FoxPro重新标记了你的问题,希望你能从仍在使用它的人那里得到帮助)
标签: c# visual-foxpro