2010-05-14 3 views
27

아래 코드 고려 : Datatable.Select을 (말을 기사의DataView.RowFilter 대 DataTable.Select()()

Dataview someView = new DataView(sometable) 
someView.RowFilter = someFilter; 

if(someView.count > 0) { …. } 

꽤 수), DataViews를 사용하는 것보다 낫다 하지만 이들은 VS2008 이전입니다. 내가 Datatable.Select을 언급 일부 기사/포럼 주제를 발견이 주제에 대한 인터넷 검색


Array of DataRecord vs. DataView: A Dramatic Difference in Performance

Solved: The Mystery of DataView's Poor Performance with Large Recordsets() 자체가 상당히 버그 (이에 대한 확인되지 않음)이며, 다양한 시나리오에 실적이 저조.

msdn에 대한이 항목 (Best Practices ADO.NET)에서는 데이터 테이블에 정의 된 기본 키가있는 경우 findrows() 또는 find() 메서드를 Datatable.Select() 메서드로 사용해야합니다.

이 기사 here (.NET 1.1)은 모든 세 가지 접근법과 두 가지를 더 벤치 마크합니다. 그러나 이것은 버전 1.1에 대한 것이므로 아직 유효한지 확실하지 않습니다. 이 DataRowCollection.Find()를 선언하면 모든 방식이 성능을 능가하며 Datatable.Select()가 DataView.RowFilter를 능가합니다.

그래서 나는 datatable에서 행을 찾는 최상의 방법이 무엇인지 혼란스러워합니다. 또는이 작업을 수행하는 좋은 방법이 하나도 없으며 시나리오에 따라 여러 가지 솔루션이 있습니까?

+0

감사합니다. – thmshd

답변

45

"데이터 테이블에서 행을 찾는 최선의 방법"을 찾고 있으므로 먼저 "최선"이라고 물어야합니다. 내 생각에, 어떤 기술에는 시나리오가있어 다른 시나리오와 잘 어울릴 수 있습니다.

우선, DataView.RowFilter을 살펴 보겠습니다. DataView는 데이터 바인딩에서 몇 가지 장점이 있습니다. 매우 뷰 지향적이어서 강력한 정렬, 필터링 또는 검색 기능을 갖추고 있지만 약간의 오버 헤드가 발생하고 성능에 최적화되어 있지 않습니다. 더 작은 레코드 세트 및/또는 다른 기능 (예 :보기에 대한 직접 데이터 바인딩)을 사용하는 곳에서는 DataView.RowFilter을 선택합니다.

이전 게시물에서 읽을 수있는 DataView에 대한 대부분의 사실은 여전히 ​​적용됩니다.

둘째, 단 하나의 히트 만 원할 경우 DataTable.Rows.FindDataTable.Select 이상으로 지정해야합니다. 왜? DataTable.Rows.Find는 단일 행만 반환합니다. 기본적으로 기본 키를 지정하면 이진 트리가 만들어집니다. 이것과 관련된 약간의 오버 헤드가 있지만, 검색 속도가 엄청나게 빠릅니다.

DataTable.Select은 더 느리지 만 여러 조건이 있고 색인화되거나 색인화되지 않은 행을 신경 쓰지 않으면 매우 유용 할 수 있습니다. 기본적으로 모든 것을 찾을 수 있지만 성능에는 최적화되어 있지 않습니다. 본질적으로 DataTable.Select는 전체 테이블을 걷고 전달한 기준과 모든 레코드를 비교해야합니다.

이 작은 개요가 도움이되기를 바랍니다.

this article을 살펴 보는 것이 좋습니다. 성능 문제와 관련하여 도움이되었습니다. 이 게시물에는 일부 인용문이 포함되어 있습니다.

약간의 UPDATE : 그런데 ,이 질문의 범위를 벗어난 조금 보일 수도 있지만 거의 항상 가장 빠른 해결책은 필터링 및 백엔드에서 검색을 할 수 있습니다.간결함을 원하고 SQL Server을 백엔드로, .NET3 +를 클라이언트에 사용하려면 LINQ-to-SQL을 사용하십시오. Linq 객체를 검색하는 것은 매우 편하며 서버 측에서 수행되는 질의를 생성합니다. LINQ-to-Objects는 매우 편안하지만 느린 기술이기도합니다. 혹시

+0

방금 ​​.Select와 RowFilter 기술간에 결과가 다른 경우를 발견했습니다. 내 경우에는 Select 532 행을 반환하고 RowFilter는 540을 반환했습니다. 테이블 데이터에서 여분의 공백과 관련이 있다는 점을 발견하고 TRIM (VendorNumber) = '500'이라는 트림을 사용하여 해결했습니다. – James

20

Thomashaid의 게시물을 멋지게 그것을 요약 .... 이미 알고하지 않았다 :

  • DataView.RowFilter 바인딩입니다.
  • DataTable.Rows.Find은 기본 키로 검색하기위한 것입니다. .
  • DataTable.Select은 여러 열로 검색하고 순서를 지정하기위한 것입니다.

루프에서 많은 DataView를 만들고 RowFilters를 사용하여 레코드를 검색하지 마십시오. 이렇게하면 성능이 크게 저하됩니다.

나는 인덱스를 이용할 수 있다는 것을 DataTable.Select에 추가하고 싶었다. 당신은 정렬 순서를 DataView를 생성 및 지정하여 DataTable을에 인덱스를 만들 수 있습니다

DataView dv = new DataView(dt); 
dv.Sort = "Col1, Col2"; 

을 그런 다음 DataTable.Select()를 호출 할 때 쿼리를 실행할 때, 그것은이 인덱스를 사용할 수 있습니다. 이 기술을 사용하여 동일한 쿼리를 여러 번 사용하는 장소의 성능을 심각하게 향상시킵니다. (이것은 Linq가 존재하기 전이었습니다.)

트릭은 Select 문에 대한 정렬 순서를 올바르게 정의하는 것입니다. 따라서 검색어가 "Col1 = 1 and Col2 = 4"인 경우 위의 예와 같이 "Col1, Col2"를 원할 것입니다.

색인 생성은 DataView를 만들기위한 실제 호출에 따라 달라질 수 있습니다. new DataView(DataTable dt) 생성자를 사용하고 별도의 단계에서 Sort 속성을 지정해야했습니다. .NET 버전에 따라 동작이 약간 다를 수 있습니다.

+1

Whoa This 슈퍼 편리한. 나는 이것이 MSDN에 문서화되어 있지 않다고 믿을 수 없다. 1 줄의 코드를 사용하여 바보 같은 FindRows() 및 Dictionary workarounds를 수행하지 않고 DataTable.Select() 호출의 성능을 크게 향상 시켰습니다. 감사합니다 –

+1

슈퍼, 그날을 보냈습니다. 이제 검색어는 300 % 빨라졌습니다! – JohanLarsson

+1

근본적인 .Net 소스를 살펴보면 조건이 맞으면 종종 .Select()가 색인 자체를 작성한다는 것을 알 수 있습니다. "col1 = 3 and col2 = 4"와 같은 간단한 표현이 사용되는 경우와 같이. 선택 후에 테이블의 비공개 [인덱스] 필드를 검사하여이를 볼 수 있습니다. 이 경우 DataView를 만들 필요가 없습니다. 위의 대답도 나를 위해 작동하지 않습니다, 난 그냥 테이블 생성자로 DataView를 만들고 [Sort] 속성을 별도로 설정해야합니다. 이유가 확실하지 않습니다 ... – LMK

관련 문제