2012-01-28 3 views
0

일부 프로젝트의 경우 SQL Server 용 재사용 가능한 데이터 액세스 계층을 만들고 있습니다. 올바른 방법으로 .NET. decimal을 쿼리 매개 변수로 전달하는 데 문제가 있습니다. 가장 확실한 방법 :십진수와 문자열을 SqlParameter로 전달하는 적절한 방법

cmd.Parameters.AddWithValue("@P0", parameterValue); 

거의 잘됩니다. 이 값은 DB에 제대로 저장되지만 SqlClient는 실제 값에서 정확한 유형을 추정하므로 응용 프로그램이 12345.678을 전달할 때 @ P0을 NUMERIC(8,3)으로 선언합니다. 정확히 같은 쿼리가 다른 값과 함께 사용되면 그 값의 정밀도와 스케일이 선언됩니다. 나에게 아직 알려지지 않은 이유로 SQL Server에서 쿼리는 동일하지 않으며 각 쿼리는 sys.dm_exec_cached_plans에 별도의 항목을 가져옵니다. string과 정확히 똑같은 문제가 있습니다. 각 쿼리 계획마다 다른 쿼리 계획이 있습니다.

몇 가지 응용 프로그램은 분당 많은 레코드를 기록하며 각 레코드는 매우 다양한 범위 (일부 센서 데이터 및 일부 통화 값)의 5-10 decimal 값을 갖습니다. 거의 각각 INSERT은 자체 쿼리 계획을 얻게되고 며칠 후 동일한 쿼리 계획의 100,000 개 이상의 버전이 캐시되고 RAM 용량은 몇 GB가 넘습니다.

제 생각은 모든 가능한 유형을 몇 가지 임의의 유형으로 합치는 것입니다. decimal의 경우 정밀도가 20보다 낮 으면 20으로 설정합니다. 정밀도가 20보다 큰 경우 실제 정밀도보다 큰 4로 나눌 수있는 최소값 (예 : 24, 28, 32, 36)으로 설정합니다. 비슷하게 규모 (최소 2, 그 다음 단계 2) 및 문자열 (최소 128, 그 다음 2의 제곱)입니다. 이 방법으로 문제를 제어 할 수 있습니다. 100k 대신 각 쿼리에 약 100 가지 변형의 계획을 보았고 SQL Server는 버퍼 풀에 메모리를 사용합니다. 쓸모없는 계획이 아닙니다.

이 방법이 잘못 될 수 있습니까? decimals이로드 된 쿼리와 SqlClient를 사용할 때 쿼리 계획 캐시를 제어 할 수있는 더 나은 방법이 있습니까?

내가 할 수없는 일들

목록 :

  • 를 사용하여 저장 프로 시저 -이 DAL의 목적은 많은 DBMS의 (순간 SQL 서버, MS 액세스, 파이어 버드, 오라클) 추상 레이어를 만들 수 있기 때문에 .
  • 내 동료 팀원이 각 변수에 실제 유형을 전달하도록 강요하십시오. 잔인하기 때문입니다.
  • 휴지통이 DAL은 보통 오래된 DbProviderFactory를 사용하고 1990처럼 매개 변수를 생성 -이 DAL도 등 SQL 언어, DB 구조 생성,
  • 휴지통이 DAL에 대한 쿼리 생성을 처리하고 NHibernate에 같은 "적절한"DAO를 사용하기 때문에 - 왜냐하면 그것은 여기에서 발명되지 않았기 때문입니다.
  • dba.stackexchange.com에이 질문을하십시오. SQL Server 자체가 아니라 SqlClient와 사용 방법에 문제가 있기 때문입니다.

답변

2

여기서 중요한 문제는 SQL 드라이버가 매개 변수의 크기, 배율 및 정밀도를 결정하도록 올바르게 지정했음을 의미합니다. 정밀도/크기/매개 변수 크기를 제한하여 쿼리 계획 수를 줄이는 아이디어도 정확합니다. 문자열의 경우 예상되는 가장 큰 값으로 크기를 설정할 수 있습니다. 쿼리가 크기가 큰 매개 변수 문자열을 작은 크기의 varchars와 비교할 때 올바르게 작동합니다. 십진수에 대한 몇 가지 정밀도를 선택하는 것도 올바르게 들립니다. 한 쌍의 정밀도/스케일로 이해할 수 있는지 확인하십시오 : 가능할 수도 있습니다 (직장에서 프로젝트를 잘 진행 했음). 관리한다면 SQL 쿼리 당 하나의 쿼리 플랜으로 갈 수 있습니다.

+0

좋은 점은 NUMERIC (38,8)에 대한 소수점 유형의 기본 유형을 설정하는 것이 좋습니다. 어떤 이유에서든 누군가 소수점 이하 8 자리 숫자를 전달하면 난 그냥 스케일을 변경하고 최대로 정밀도를 유지할 것입니다. 이제 왜 내가 varchar (8000)와 numeric (38,8 + n) 대신에 많은 가치를 가진 복잡한 생각을 떠올리게되었는지 궁금하다고 말했을 때. – MagnatLU

관련 문제