버튼을 클릭하고 이벤트 핸들러에서 내용을 처리 중일 때는 버튼을 잠시 잠그고 처리 완료 후 버튼의 잠금을 해제하여 이중 클릭 방지와 처리 과정이 동작 중임을 가시적으로 표현하곤 한다. 이 때에 필요한 방법을 4가지 정도로 소개할까 한다. 테스트 환경은 .NET 8.0 WPF 이다.
일반적으로 간단하게 처리하고자 한다면 아래와 같이 코드를 작성할 것이다.
public static void ButtonOnTest(object sender, RoutedEventArgs e)
{
if (sender is not Button btn)
{
return;
}
string? orgContent = btn.Content?.ToString();
try
{
btn.Content = "처리중...";
btn.IsEnabled = false;
// 해당 작업이 있다고 가정
Thread.Sleep(5000);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message); // Log처리 가정
}
finally
{
btn.Content = orgContent;
btn.IsEnabled = true;
}
}
위의 코드는 문제가 2가지 정도 있는데 하나는 동작 중에 화면이 잠기는 것이고 두 번째는 이중 클릭을 방지할 수 없다는 것이다. 아래의 코드는 비동기 방식으로 처리하여 간단하게 개선한 것이다.
데이터베이스는 기본적으로 ‘select’와 같이 조회했을 때 그 결과가 운반 단위(array)에 도달하면 호출한 쪽으로 그 결과를 바로 리턴해준다. 예를 들어 어떤 테이블에 row 개수가 1000만 개가 있든 10만 개가 있든지 상관없이 select * from tablename
을 실행하면 바로 화면에 나와야 정상이다.
이 부분을 간과하고 조회하는 프로그램 작성한다고 하면 조회 결과를 어떠한 DataSet에 넣고 그 결과가 완료될 때 비로서 Loop을 사용하여 화면에 표현하기 때문에 row 개수에 영향을 받는다. 물론, 페이징 처리를 한다고 하지만 쿼리문 자체에 ‘order by’, ‘group by’ 등을 사용하면 Sort가 발생하고 이 모든 정렬이 끝나야 비로소 그 결과를 출력하기 시작한다. 즉, ‘부분범위처리’와 ‘전체범위처리’의 차이다.
부분범위처리’라 함은 데이터베이스가 해당 내용을 다 읽지 않고도 바로 하나의 row를 바로 출력할 수 있는 상태를 말한다. 옵티마이저가 봤을 때 끝까지 읽어서 분석할 필요가 없다고 판단하기 때문이다. 그래서 정렬하되 전체범위처리(끝까지 다 읽고나서야 결과를 뽑아낼수 있는 상태)가 되지 않도록 쿼리문을 잘 작성해야 한다.
여기에는 인덱스 전략도 포함되며 특히, ‘where’절에 column을 가공하면(예, where left(xxxx) = '1234'
) 작성한 ‘left(xxxx)’라는 column은 존재하지 않기 때문에 옵티마이저는 전체를 다 읽고 해당 column을 ‘left(xxxx)’로 모두 2차 가공한 다음에 조회하고 그 결과를 출력한다. 즉, 전체범위처리를 하는 것이다. 요지는 ‘어떻게 부분범위처리가 되도록 유도하느냐’이다.
부분범위처리가 되었다고 가정하고 조회 결과를 클라이언트의 프로그램에서 조회한 결과를 DataSet에 모두 넣고 그 다음에 화면에 Loop를 사용하여 표현하는 방법으로 처리하는 것이 아닌 비동기적으로 스트리밍하여 그 결과가 들어오는 즉시 화면에 출력하도록 IAsyncEnumerable
, yield return
을 사용하는 예제를 작성해 보았다. SQL Server의 특정 테이블에 50만 개 정도의 row가 저장된 테스트 데이터를 사용한다.
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Dapper" Version="2.1.35"/>
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.0.0-preview3.24332.3"/>
<PackageReference Include="System.Linq.Async" Version="6.0.1" />
</ItemGroup>
</Project>
Database 시장에서 점유율의 순위는 크게 변화하지는 않았지만, 주목할 만한 것은 PostgreSQL의 상승세이다.1 특히 MySQL의 점유율은 갈수록 하락 추세이다. 물론 MariaDB 사용자를 포함하지 않아서일 수도 있다.2 오라클의 장점을 가지면서도 오픈소스로써 무료 데이터베이스인 PostgreSQL의 설치와 설정 과정, 튜닝포인트를 알아보고 MVCC(multiversion concurrency control)의 차이점 또한 간략하게 정리하였다.
테스트를 사용한 환경은 Windows WSL2에 Ubuntu 24.04 LTS 버전을 설치하여 진행했다.3 ?>
는 Shell 프롬프트이다.
?> sudo apt install postgresql postgresql-contrib
?> sudo systemctl status postgresql
?> sudo systemctl enable/disable postgresql
?> sudo systemctl start postgresql
?> sudo -i -u postgres psql
\password postgres #패스워드
?> sudo vi /etc/postgresql/14/main/postgresql.conf
isten_addresses = '*'
?> sudo vi /etc/postgresql/14/main/pg_hba.conf
host all all 0.0.0.0/0 md5 #추가 또는 수정