2009-06-23 4 views
2
select rectype,jobid,jobrecid,template,assignedto,entereddt,enteredby,ref1,processed,processeddt, 
processbydt,title,description,connectlanhandle,finished,updateddt,ref2,cancelled, 
requireaccept,acceptrejectstate,acceptrejectbydt,alert1dt,alert2dt,alert3dt,despatchallowed, 
flag,ref3,projectid,duration,skillset,postcode,prefschedulefrom,prefscheduleto,customdata1, 
customdata2,customdata3,hasnotes,displayjobtype,createdby,createddt,colour 
from jobs 
where updateddt >= '1982-02-05 17:25:38' 
or (processed = 'N' and 
    cancelled = 'N') 
order by jobid, jobrecid 

이 쿼리는 ~ 80000 개의 결과를 반환합니다. SQLyog (MySQL GUI)는 ~ 600ms 내에 눈금에서 결과를 반환 할 수 있습니다. ODBC (최신 MyODBC 드라이버)를 사용하여 연결하는 My Delphi 프로그램은 결과를보기 시작하지 않고 쿼리를 수행하는 데 ~ 6000ms 정도 걸립니다.SQLyog가 내 Delphi 프로그램보다 10 배 빠른 MySQL 쿼리 결과를 반환하는 이유는 무엇입니까?

프로그램을 더 빨리 만들 수있는 방법에 대한 아이디어가 있습니까?

답변

5

기본 테이블 (조인 없음)에서이 자체를 시도했으며 "모두 표시"확인란을 클릭하더라도 SQLyog는 모든 결과를 즉시 그리드에 가져 오지 않고 스크롤 단추를 움직여보십시오 가장 낮은 영역으로 갈수록 sqlyog가 잠시 느려지고 더 많은 결과를 보여줄 것입니다.

또한 ODBC는 기본 액세스에 더 많은 레이어를 추가하므로 속도가 느린 것으로 알려져 있으므로(mysql 클라이언트 라이브러리가없는 경우에도)에 대한 직접 액세스를 사용하십시오.

대부분의 경우 사용자가 한 번에 80,000 개의 레코드를 표시하지 않습니다.

은 BTW, 태양으로부터 공식 MySql GUI tools 사용하여 내장 델파이 ;-)

6

제 생각에 SQLyog는 실제로 600ms에서 80,000 개의 결과를 모두 표시하지 않았습니다. 첫 번째 항목을 표시하는 동안 나중의 항목을로드 할 수 있습니다. (특히, 내가 본 대부분의 GUI 프레임 워크는 데이터베이스가 개입되지 않아도 빠르게 80,000 개의 행을 채울 수 없습니다.)

사용중인 API를 사용한다고 가정하면 똑같은 작업을 시도해 볼 수 있습니다 호출이 반환되기 전에 모든 것을 메모리로 전송하는 대신 스트리밍 방식으로 결과를 얻습니다.

+0

은 내가 SQLyog에는 그리드의 보이는 부분의 행을 표시하여, 가능한 한 빨리 GUI를 새로 고치려면 "트릭"을 사용 할 수 있음을 동의하고 그룰 테이머 "와 같은 격자를 업데이트 카라 "는 아래에서 설명합니다. – TFM

0

제 생각에는 응용 프로그램 및/또는 데이터베이스 아키텍처에 대해 두 번 생각해야합니다. 80K 레코드를 다루는 것은 좋지 않습니다. 검색 범위를 좁히십시오. 아무리해도 간단하지 않으면 아무도하지 않으실 겁니다.

+0

우리는 그렇게 할 것이지만 많은 일이 있습니다. 어딘가에서 설정을 변경하여 몇 초를 절약 할 수 있다면 좋을 것입니다! – cja

1

OnAfterScroll 이벤트를 체크하여 쿼리에 LIMIT 0,1000을 사용하고 사용자가 원거리에 도달하면이를 변경할 수 있습니다.

+0

고마워요.하지만 내 프로그램 전체에서 사용되는 개체의 내부 배열을 채우고 있습니다. 때로는 목록을 표시하기도하지만 때로는 표시하지 않는 경우가 있습니다. 프로그램 시작시에만이 쿼리를 수행합니다. – cja

2

ODBC 커넥터를 사용하는 반면 SQLyog는 기본 MySQL C API (직접 연결)를 사용하기 때문입니다. Devart에서 MyDAC와 같은 타사 커넥터를 사용해 보셨습니까? 거기에서 무료 평가판을 가져 와서 응용 프로그램을 테스트 할 수 있습니다. ,

0

SQLyog에 아마 한 번에 모든 80,000 행을로드 할 수 없습니다 적어도 일부 데시벨 도구를

FWIW는 지금 년 동안 MyDac을 사용하고 있는데 나는 (성능/상/지원) 정말 기쁘게 생각하는 I 스크롤 할 때 "요구시로드"를 사용하십시오. 쿼리를 실행하고 내부 배열을 채우기 위해 스레드를 사용하는 것을 고려하여 모든 레코드를 한꺼번에 가져와야하는 경우.

2

다른 사람들이 말했듯이 SQLyog에 모든 레코드를로드, 아마 200 정도에 제한되지 않기 때문에, 그것은 가능성이 높습니다.

이 성능 문제를 해결하기 위해 비열한 트릭을 사용할 수 있습니다. 기본적으로 시작할 때 응용 프로그램에 데이터 집합의 캐시를로드하므로이 스레드를 스레드 할 수 있습니다. 로드하는 데 여전히 6 ~ 8 초가 걸리지 만 응용 프로그램은 여전히 ​​시작되고 UI는 사용할 수 있습니다. 캐시가로드되기 전에 누군가가 캐시를 필요로하는 작업을 수행하면 캐시가 준비 될 때까지 모래 시계 커서 또는 "잠시만 기다려주십시오."라는 메시지를 표시 할 수 있습니다.

스레드에서 데이터 액세스를 할 때주의해야 할 점은 일반적으로 스레드에 별도의 데이터베이스 연결을 만들어야한다는 것입니다. 다음과 같은 내용 :

type 
    TLoadCacheThread = class(TThread) 
    private 
    FConnection : TODBCConnection; // Or whatever, I don't use ODBC :-) 
    FQuery : TODBCQuery; 
    FMemData : TkbmMemTable; // This is what I use, YMMV 
    protected 
    procedure PopulateCachedDataset; 
    public 
    constructor Create; override; 
    procedure Execute; override; 
    end; 

constructor Create; 
begin 
    inherited Create(True); // create suspended thread 
    FConnection := TODBCConnection.Create(nil); 
    // Set any properties for the connection here. 
    FQuery := TODBCQuery.Create(nil); 
    // Set any properties for the query here. 
    FQuery.SQL.Text := 'select * from mytable'; 
    Resume; 
end; 

procedure Execute; 
begin 
    FQuery.Open; 
    FMemTable.LoadFromDataset(FQuery); 
    Synchronize(PopulateCachedDataset); 
end; 

// The idea here is that you're loading into a mem dataset, which can then 
// quickly be copied to another memory dataset, rather than loading the 
// cached data directly from FQuery, which is slow and why we're threading 
// in the first place. This assumes you have some kind of globalsettings unit 
// or class, and it has a cacheddataset variable or property. 
procedure PopulateCachedDataset; 
begin 
    GlobalSettings.CachedDataset.LoadFromDataset(FMemTable); 
end; 

어쨌든 기본 아이디어입니다. GlobalSettings.CachedDataset을 주문형 데이터로로드하는 것과 같이 복잡하지만 기술적으로 우수한 다른 방법이 있으므로 처음 액세스 할 때 느려지지만 후속 시간은 더 오래 걸릴 것입니다. 그러나 당신의 필요에 달려 있습니다.

HTH

+0

이 질문에 대한 답변의 품질과 속도는 환상적입니다. 계속가요 :) – cja

관련 문제