성능 고려 사항 : 여러 테이블에 행을 스프레드하는 것과 한 테이블에 모든 행을 집중시킵니다.

StackOverflow https://stackoverflow.com/questions/1142296

문제

성능 고려 사항 : 여러 테이블에 행을 널리 퍼 뜨리십시오.

안녕.

SQL DB의 응용 프로그램에서 진행되는 모든 단계에 대한 정보를 기록해야합니다. 특정 테이블이 있습니다. 로그가 다음과 관련이 있기를 원합니다.

데이터를 자주 검색해야합니다.

나는 그것을하는 방법에 대한 아이디어가 거의 없습니다.

  1. 이 모든 테이블에 대한 열이 포함 된 로그 테이블이있는 다음 특정 제품에 대한 UI의 데이터를 표현하려는 경우 logid = product.productid에서 로그에서 *를 선택합니다. 나는 이것이 많은 Cols를 갖는 것이 재미 있을지도 모른다는 것을 알고 있지만, 나는 성능이 더 나아질 것이라고 생각합니다. 반면 에이 테이블에는 엄청난 양의 행이있을 것입니다.
  2. 각 로그 유형 (ProductLogs, OrderLogs 등)에 대해 많은 로그 테이블이 있습니다.이 아이디어는 일관되지 않고 동일한 구조를 가진 많은 테이블을 가지고 있기 때문에이 아이디어가 마음에 들지 않지만 검색 할 때 더 빠를 수 있습니다. 적은 양의 행이있는 테이블에서 (mi 잘못?).
  3. 진술 번호에 따라. 1, 나는 logid, tablenameid 및 rowid cols를 갖는 두 번째 다중 테이블을 할 수 있으며, 데이터를 검색하는 UDF가있는 것보다 DB의 많은 테이블 행에 로그 행을 참조 할 수 있습니다 (예 : 로그 ID 234 CustomerID 345의 테이블 고객과 제품 테이블에 속합니다. 나는 이것이 가장 좋은 방법이라고 생각하지만 다시, 많은 양의 행이있을 수 있습니다. 검색 속도가 느려질까요? 아니면 이것이 어떻게 해야하는지, 뭐라고 말하는가? ...

위 목록에서 3 번의 예 :

CREATE TABLE [dbo].[Log](
    [LogId] [int] IDENTITY(1,1) NOT NULL,
    [UserId] [int] NULL,
    [Description] [varchar](1024) NOT NULL,
 CONSTRAINT [PK_Log] PRIMARY KEY CLUSTERED 
(
    [LogId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
ALTER TABLE [dbo].[Log]  WITH CHECK ADD  CONSTRAINT [FK_Log_Table] FOREIGN KEY([UserId])
REFERENCES [dbo].[Table] ([TableId])
GO
ALTER TABLE [dbo].[Log] CHECK CONSTRAINT [FK_Log_Table]
---------------------------------------------------------------------
CREATE TABLE [dbo].[LogReference](
    [LogId] [int] NOT NULL,
    [TableName] [varchar](32) NOT NULL,
    [RowId] [int] NOT NULL,
 CONSTRAINT [PK_LogReference] PRIMARY KEY CLUSTERED 
(
    [LogId] ASC,
    [TableName] ASC,
    [RowId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[LogReference]  WITH CHECK ADD  CONSTRAINT [FK_LogReference_Log] FOREIGN KEY([LogId])
REFERENCES [dbo].[Log] ([LogId])
GO
ALTER TABLE [dbo].[LogReference] CHECK CONSTRAINT [FK_LogReference_Log]
---------------------------------------------------------------------
CREATE FUNCTION GetLog
(   
    @TableName varchar(32),
    @RowId int
)
RETURNS 
@Log TABLE
(       
    LogId int not null,
    UserId int not null,
    Description varchar(1024) not null
)
AS
BEGIN

INSERT INTO @Log
SELECT     [Log].LogId, [Log].UserId, [Log].Description
FROM         [Log] INNER JOIN
                      LogReference ON [Log].LogId = LogReference.LogId
WHERE     (LogReference.TableName = @TableName) AND (LogReference.RowId = @RowId)
    RETURN 
END
GO
도움이 되었습니까?

해결책

나는 몇 가지 이유로 옵션 3을 확실히 갈 것입니다.

데이터는 테이블 이름 (옵션 2) 또는 필드 이름 (옵션 1)이 아닌 테이블 필드에 있어야합니다. 이렇게하면 데이터베이스가 작업하기가 더 쉬워지고 유지 관리가 쉬워집니다.

좁은 테이블 장기 성능이 더 잘 작동합니다. 행의 수는 필드 수보다 성능에 미치는 영향이 적습니다.

각 테이블에 대한 필드가있는 경우 (옵션 1), 몇 개의 테이블 만 작동의 영향을 받으면 빈 필드가 많이 발생할 수 있습니다.

다른 팁

사전 최적화 데이터베이스에주의하십시오. 대부분의 데이터베이스는 합리적으로 빠르고 다소 복잡합니다. 먼저 효율성 테스트를 실행하고 싶습니다.

두 번째로 한 테이블에 모든 것을 넣으면 원하는 결과가 캐시에있을 가능성이 높아져 성능이 크게 향상됩니다. 불행히도 그것은 또한 당신이 찾고있는 것을 찾기 위해 거대한 테이블을 검색해야 할 가능성이 훨씬 높아집니다. 이것은 부분적으로 인덱스로 해결 될 수 있지만 인덱스는 무료로 제공되지 않습니다 (하나는 더 비싸게됩니다).

저의 조언은 성능이 실제로 중요한지 확인한 다음 다른 시나리오를 테스트하여 가장 빠른지 확인하는 것입니다.

대량의 데이터 (수백만 행+)에 대해 이야기하고 있다면 다른 테이블을 사용하여 저장하면 이점을 얻을 수 있습니다.

예를 들어 기본 예제 5 천만 개의 로그 항목, 5 개의 다른 "유형"이 1 x 5 천만 행 테이블보다 5 x 천만 행 테이블을 갖는 것이 더 좋습니다.

  • 개별 테이블을 사용하면 성능 삽입이 더 좋습니다. 각 테이블의 인덱스는 더 작아서 삽입 작업의 일부로 업데이트/유지하기가 쉽습니다.

  • 개별 테이블을 사용하면 성능을 읽는 것이 더 좋습니다 - 쿼리에 대한 데이터가 적고, 더 작은 인덱스가 통과합니다. 또한 레코드가 어떤 유형의 로그 항목인지 식별하기 위해 추가 열을 저장 해야하는 것처럼 들립니다 (제품, 배송 ...)

  • 더 작은 테이블의 유지 보수는 덜 고통 스럽습니다 (통계, 색인 배설/재건 등)

본질적으로 이것은 데이터를 분할하는 것입니다. SQL 2005에서 파티셔닝을 지원했습니다 (참조 여기) 그러나 기본적으로 엔터프라이즈 에디션이 필요합니다. 기본적으로 한 테이블에서 데이터를 분할하여 성능을 향상시킬 수 있습니다 (예 : 하나의 로그 테이블이있는 다음 해당 내의 데이터가 분할되는 방법을 정의합니다).

나는 최근 eBay 건축가 중 한 명과의 인터뷰를 들었습니다. 최근에는 성능과 확장 성이 필요할 때 파티셔닝의 중요성을 강조했으며 내 경험에 근거하여 강력하게 동의합니다.

필요한 경우 한 데이터베이스 모델에서 다른 데이터베이스 모델로 변경할 수 있도록 데이터 액세스 계층을 구현하십시오.이 방법으로는 하나를 선택하고 나중에 성능에 대해 걱정하십시오.

성능 테스트를 수행하고 성능이 읽기 수, 쓰기 수 및 여부와 같은 여러 요인에 달려 있기 때문에 최적화하기가 어려울 것입니다. 또는 읽기와 쓰기가 충돌하고 잠금을 일으킬 가능성이 없습니다.

옵션 1 BTW에 대한 선호는 가장 간단하고 가장 간단하고 다양한 종류의 문제를 해결하기 위해 할 수있는 많은 조정이 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top