복붙노트

[SQL] SQL 서버 수는 느린

SQL

SQL 서버 수는 느린

많은 양의 데이터가있는 테이블을 계산하는 것은 때때로 분 소요, 매우 느려질 수 있습니다; 또한 바쁜 서버에서 교착 상태 발생시킬 수있다. 내가 실제 값을 표시하려면, NOLOCK를 선택할 수 없습니다.

내가 사용하는 서버는 SQL Server 2005 또는 2008 Standard 또는 Enterprise - 그것은 중요합니다. 나는 SQL 서버는 모든 테이블의 수를 유지하고 더있는 경우 WHERE 절 내가 꽤 빨리 바로 그 번호를 얻을 수 있다는 것을 상상할 수 있는가?

예를 들면 :

SELECT COUNT(*) FROM myTable

바로 올바른 값을 반환해야합니다. 나는 업데이트 할 통계에 의존해야합니까?

해결법

  1. ==============================

    1.대략 아주 가까이 될 것 (모든 기내 트랜잭션을 무시) :

    대략 아주 가까이 될 것 (모든 기내 트랜잭션을 무시) :

    SELECT SUM(p.rows) FROM sys.partitions AS p
      INNER JOIN sys.tables AS t
      ON p.[object_id] = t.[object_id]
      INNER JOIN sys.schemas AS s
      ON s.[schema_id] = t.[schema_id]
      WHERE t.name = N'myTable'
      AND s.name = N'dbo'
      AND p.index_id IN (0,1);
    

    이것은 (*) COUNT보다 훨씬 빨리, 훨씬 반환하고 테이블이 충분히 빠르게 변화하는 경우, 정말 덜 정확하지 않습니다 - 그것은이 때 테이블은 당신이 당신의 COUNT를 시작했을 때 사이의 변경 (및 잠금 찍은) 및 경우 (잠금이 해제 된 모든 대기 쓰기 트랜잭션이 이제 테이블에 쓰기에 허용 된 경우), 반환이 훨씬 더 가치가있다? 그렇게 생각하지 않아요.

    당신은 당신이 (some_column가 NULL의 말을) 계산하려는 테이블의 일부 부분 집합이있는 경우는 예외는 아니었다 여부에 따라, where 절 방법은 하나 또는 다른 그 열에 대한 필터링 된 인덱스를 생성하고 구조화 할 수 규칙은 (매우 작은 세트의 필터링 된 인덱스를 생성). 이 두 지수 중 하나 그래서 :

    CREATE INDEX IAmTheException ON dbo.table(some_column)
      WHERE some_column IS NULL;
    
    CREATE INDEX IAmTheRule ON dbo.table(some_column)
      WHERE some_column IS NOT NULL;
    

    그럼 당신은 사용하여 비슷한 방법으로 수를 얻을 수 있습니다 :

    SELECT SUM(p.rows) FROM sys.partitions AS p
      INNER JOIN sys.tables AS t
      ON p.[object_id] = t.[object_id]
      INNER JOIN sys.schemas AS s
      ON s.[schema_id] = t.[schema_id]
      INNER JOIN sys.indexes AS i
      ON p.index_id = i.index_id
      WHERE t.name = N'myTable'
      AND s.name = N'dbo'
      AND i.name = N'IAmTheException' -- or N'IAmTheRule'
      AND p.index_id IN (0,1);
    

    당신이 반대를 알고 싶은 경우에, 당신은 위의 첫 번째 쿼리에서 뺍니다.

  2. ==============================

    2.(-이 먼저 댓글을 달았지만, 아래 어쩌면 간부는 이미 당신을하는 데 도움이해야? 얼마나 큰 것은 "많은 양의 데이터가")

    (-이 먼저 댓글을 달았지만, 아래 어쩌면 간부는 이미 당신을하는 데 도움이해야? 얼마나 큰 것은 "많은 양의 데이터가")

    내가 정적에 쿼리를 실행하면 내 dev에 기계 15 초 2 억 행과 COUNT (*) (테이블 (경합이 문제가되지 않도록하면서 수단 아무도 꽤에서 읽기 / 쓰기 / 업데이트 성가신) 신탁). 데이터의 순수한 양을 고려하면,이 (적어도 나에게) 여전히 매우 빠르다

    당신이 NOLOCK이 옵션을 선택하지 않습니다 말했듯이, 당신은 고려할 수

    exec sp_spaceused 'myTable'
    

    게다가.

    그러나이 핀 아래로 거의에 NOLOCK과 같은 (무시 경합 + 삭제 / 업데이트 AFAIK)

  3. ==============================

    3.카운트는 테이블 스캔 또는 인덱스 스캔 하나를 수행합니다. 그래서 행의 높은 번호가 느려질 수 있습니다. 자주이 작업을 할 경우, 가장 좋은 방법은 다른 테이블에서 카운트 기록을 유지하는 것입니다.

    카운트는 테이블 스캔 또는 인덱스 스캔 하나를 수행합니다. 그래서 행의 높은 번호가 느려질 수 있습니다. 자주이 작업을 할 경우, 가장 좋은 방법은 다른 테이블에서 카운트 기록을 유지하는 것입니다.

    당신이 그렇게하고 싶지 않아 그러나, 당신은 더미 인덱스를 만들 수있는 경우 (즉,이에 의해 사용되지 않습니다 쿼리의) 및 쿼리 항목의 그것의 수, 같은 :

    select 
        row_count
    from sys.dm_db_partition_stats as p
    inner join sys.indexes as i 
      on p.index_id = i.index_id
      and p.object_id = i.object_id
    where   i.name = 'your index'
    

    이 사람이 (그것을 사용하지 않을 경우) 다른 작업을 수행하는 동안 고정되지 않습니다 때문에, 새로운 인덱스를 생성 제안하고있다.

    아론 버트 랜드가 말했듯이, 쿼리를 유지하는 것은 다음 이미 존재하는 하나를 사용하여 더 많은 비용이 많이들 수 있습니다. 그래서 선택은 당신입니다.

  4. ==============================

    4.나는 지난 해 그것을 쉽고 빠르게 당신이 대답 덕분에이 정보를 제공 할 수 있음을 발견 잘 십년 만에 대한 SSMS와 협력했습니다.

    나는 지난 해 그것을 쉽고 빠르게 당신이 대답 덕분에이 정보를 제공 할 수 있음을 발견 잘 십년 만에 대한 SSMS와 협력했습니다.

  5. ==============================

    5.당신은 즉, 행 수의 대략적인 수를 필요로합니다. 확인 테이블이 제대로로드하거나 다음을 수행하십시오 데이터가 삭제되지 않았습니다 수 있도록합니다 :

    당신은 즉, 행 수의 대략적인 수를 필요로합니다. 확인 테이블이 제대로로드하거나 다음을 수행하십시오 데이터가 삭제되지 않았습니다 수 있도록합니다 :

    MySQL> connect information_schema;
    MySQL> select table_name,table_rows from tables;
    
  6. from https://stackoverflow.com/questions/12479677/sql-server-count-is-slow by cc-by-sa and MIT license