WinForm 응용 프로그램에서 DBF 파일의 데이터를 표시하는 인터페이스에서 작업 중입니다. OdbcConnection을 사용하기 시작했습니다. 작동했지만 Visual FoxPro 드라이버의 특정 제한 (서브 쿼리는 지원되지 않음)으로 인해 OLEDB (VFPOLEDB)를 사용하여 전환했습니다. 이제 복잡한 쿼리를 실행할 수 있지만 해결해야 할 새로운 어려움이 나타났습니다. 문제는 이러한 쿼리가 너무 느리다는 것입니다. 예상보다 100 배 느립니다.
아래는 데모 코드입니다. DBF 테이블 'PROD'가 있습니다. 인덱싱 된 필드 PRICE_N은 쿼리의 Where 절에서 사용됩니다. 테이블은 애플리케이션이 실행되는 동일한 PC에 있습니다. 보시다시피 ODBC (Microsoft Visual FoxPro Driver)와 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)의 경우 인덱스가 사용되지 않는다는 인상이 있습니다. 결과가 만족스럽지 않아 사용할 인덱스가 필요합니다.
누군가 제안이 있으면 매우 감사하겠습니다.
@Sergiy, 당신을위한 해결책이있을 수 있습니다 :
string sqlEq = "SELECT utk_ved FROM prod WHERE Price_N = '641857'";
string sqlLike = "SELECT utk_ved FROM prod WHERE Price_N like '641857'";
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(sqlEq, 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(sqlLike, 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();
new OleDbCommand("set enginebehavior 80", oleDbCon).ExecuteNonQuery();
OleDbCommand oleDbcommand = new OleDbCommand(sqlEq, 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(sqlLike, 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());
동일한 연결 에서이 줄 을 참고하십시오 .
new OleDbCommand("set enginebehavior 80", oleDbCon).ExecuteNonQuery();
결과에는 영향을 미치지 않지만 원하는 것을 얻을 수 있습니다. 내 머리 위에 영향을 미칠 수있는 유일한 위치는 "그룹 별"쿼리입니다. 오래된 버그가있는 VFP 방식으로 쿼리로 그룹을 작성하지 않을 것이라고 생각하면 안전해야합니다.
"Set EngineBehavior 80"이없는 내 타이밍 :
Time spent via ODBC(milliseconds) using '=' to compare - 4.0002
Time spent via ODBC(milliseconds) using 'Like' to compare - 1.0001
Time spent via OLEDB(milliseconds) using '=' to compare - 352.0201
Time spent via OLEDB(milliseconds) using 'Like' to compare - 659.0377
"Set EngineBehavior 80"사용 :
Time spent via ODBC(milliseconds) using '=' to compare - 3.0001
Time spent via ODBC(milliseconds) using 'Like' to compare - 2.0002
Time spent via OLEDB(milliseconds) using '=' to compare - 15.0008
Time spent via OLEDB(milliseconds) using 'Like' to compare - 3.0002
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다