2010-07-20 5 views
0

나는 MySQL 사용자였습니다. 이제 SQL Server로 마이그레이션 중입니다. 그러나 나는 문제가있다. 나는 테이블에있는 인덱스의 종류를 구체화 할 방법을 찾을 수 없다. MySQL에서는 BTree 인덱스 또는 해시 인덱스를 쉽게 생성 할 수 있습니다. 여기서 어떻게 할 수 있습니까?SQL 서버 인덱스

주요 문제는 두 개의 테이블이 있다는 것입니다. 그 중 하나 ("게시물"이라는)는 "id"에 대한 기본 키 제약 조건이있는 다른 키 ("사용자"라고 함)에 대한 외래 키를 가지고 있습니다. 게시물 삽입을위한 자바 프로그램에서이 게시물의 사용자가 삽입되었는지 아닌지를 확인해야합니다. 삽입하지 않으면 삽입하십시오 (모든 사용자를 먼저 삽입 할 수 없습니다!).

이 코드는 MySQL에서 매 10 초마다 약 1000 개의 게시물을 삽입했습니다. 그러나 SQL Server에서는 검색 부분이 너무 많은 시간이 걸리고 1000 개의 게시물이 1 분 이상 걸립니다.

이 느린 SQL 쿼리입니다 :

CREATE TABLE [dbo].[users](
[id] [varchar](50) NOT NULL, 
[type] [char](1) NULL, 
[name] [nvarchar](150) NULL, 
[reserved] [char](8) NULL, 
[description] [nvarchar](4000) NULL, 
[text] [ntext] NULL, 
CONSTRAINT [PK__users__3213E83F00551192] PRIMARY KEY CLUSTERED 
(
    [id] ASC 
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] 
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] 

문제가 무엇 :

select * from users u where u.id = "UserName" 

이 사용자 테이블 인?

감사합니다.

+1

당신은 당신이 최적화 된 SQL 문을 포함 할 수 있습니다? – JohnFx

+0

질문에 포함 시켰습니다. This is : select * from users u where u.id = "UserName" – Shayan

+0

사용자 테이블이 거대한데도 (user.id가 PK라고 가정하고) 너무 오래 걸릴 수는 없다. BTW, 만약 당신이 필요한 모든 사용자가 있는지 확인하는 것입니다, 당신은 테이블에서 전체 레코드를 검색 할 필요가 없습니다 (단지'SELECT id ...'또는'SELECT 1 ..'로 충분합니다) – a1ex07

답변

1

SQL Server는 해시 인덱스를 지원하지 않습니다. 사용 가능한 인덱스 목록은 here입니다.

초당 수천 개의 레코드를 삽입하려는 경우 BULK INSERT을 사용하는 것이 더 나을 것 같습니다. 이상적으로 다음을 수행하십시오.

  • 모든 사용자를 대량으로 삽입하십시오.
  • 모든 메시지를 대량 삽입하십시오.

    • 당신의 외래 키 제약 조건을 제거합니다

  • 먼저 나는 이런 식으로 뭔가를 제안하는 모든 사용자를 삽입 할 수있는 귀하의 요구 사항을 감안할 때.
  • 모든 메시지를 대량으로 삽입하십시오.
  • 누락 된 사용자를 찾아서 삽입하려면 쿼리하십시오 (하나의 명령문에서 수행 할 수 있음).
  • 제약 조건을 다시 추가하십시오.
+0

합리적인 것 같습니다. – Shayan

2

MySQL에서 나는 쉽게 BTree 색인 또는 해시 색인을 작성한다고 말할 수 있습니다.

인덱스는 ANSI 표준이 아니므로 데이터베이스 공급 업체 간의 유사점은 놀라운 사실입니다. 또한 MySQL과 SQL Server는 다른 쌍보다 더 유사합니다 ... While SQL Server doesn't allow you to specify indexes as BTREE or HASH, there are other controls exposed that are not provided by MySQL.

최적화 방법에 대한 의견을 보내 주시기 바랍니다. 다음을 가정하면 참조하는 것입니다 : 모든 열이 반환에서 당신이 데이터를 사용하는 경우

select * from users u where u.id = "UserName" 
  1. SELECT *에만 유효합니다. 많은 양의 텍스트가 포함 된 열은 쿼리 성능에 부정적인 영향을 줄 수 있습니다.이상적으로 절대 사용하지 마십시오 SELECT * - 항상 사용중인 열에 대해 명시해야합니다. SELECT * 성능 및 피하는 방법에 관해서는 많은 질문이 있습니다. 이
  2. 를 사용하여 작은 따옴표, 두 배 SQL에서 문자열을 표시하지 않은 INT 것처럼
  3. ID 값으로 문자열을 저장하면 빨리되지 않습니다 당신이를 만들어야합니다
+0

select * from us u.id = "UserName" – Shayan

+0

이 쿼리는 MySQL에서 매우 빠릅니다. – Shayan

+1

@Shayan : MySQL은 완전히 다른 데이터베이스입니다. 높은 수준에서 사과와 사과를 비교하지만 실제로는 맥 사과와 크랩 사과를 비교하는 것과 같습니다. –

1

첫 번째 방법 색인은 기본 키를 만드는 것입니다. 고유 한 색인이 연관되어 있습니다. u.id가 고유 값을 포함하면 u.id 열이 기본 키의 후보가 될 수 있습니다. u.id이 고유하지, 또는 당신이 기본 키가되고 싶지 않은 경우

, 당신은 다음과에 인덱스를 만들 수 있습니다

CREATE INDEX ix_users_id 
ON users (id) 
; 

것은 아마 당신에게 더 나은 성능을 줄 것이다 당신이 보여주는 쿼리에.

물론 다른 설명과 같이 색인 전략을 완전히 디자인하려면 이보다 더 많은 작업이 필요합니다.

+0

글쓰기를 깜박했습니다. id에 대한 기본 키 제약 조건이 있습니다. – Shayan

+0

기본적으로 SQL Server는 테이블에 CLUSTERED 키가 이미 정의되어 있지 않으면 기본 키에 CLUSTERED 인덱스를 정의합니다. CLUSTERED 인덱스가 반드시 기본 키 열에 첨부된다는 것을 의미하지는 않지만 가능성이 있습니다. –

+0

클러스터 된 인덱스가 있습니다. – Shayan

0

게시물의 검색어가 실행중인 검색어 정확히입니까? 아무리 뛰어 다니더라도 select * from users u where u.id = @userName 일 수 있습니까?

응용 프로그램 개발에서 가장 일반적으로 발생하는 문제는 ASCII 열을 찾는 유니 코드 매개 변수입니다. 이것은 NHibernate에서 매핑 유형의 간단한 실수로 코드에 들어가거나, SqlCommand.Parameters.AddWithValue("@userName", Request["userName"]); 또는 somehtig와 유사한 매개 변수를 추가 할 수 있습니다. 결과는 SQL data type precendence의 규칙으로 인해 검색이 대신 검색을 수행한다는 것입니다.

나는 이것이 귀하의 문제라고 말하지 않습니다. 저는 여러분이 질의 계획의 틀린면에 여러분을 모셔 왔을지도 모르는이 모든 종류의 작은 것들이있을 수 있다고 말하고 있습니다. 운좋게도 문제를 해결하고 조사 할 수있는 도구가 있습니다. 좋은 출발자는 다음과 같습니다 : Troubleshooting Performance Problems in SQL Server 2005. 보조 노트로

, BTREE 인덱스, 당신은 해시 인덱스를 필요로하지 않는 엄청나게 빠르다)