プレビュー提供中の、Amazon Redshift クエリエディタのAmazon Q generative SQLを試してみた

クエリエディタv2上で英語のテキストチャットをするだけで、接続したデータベースに対するSQLを生成してくれるとても便利な機能でした!
2023.12.08

データアナリティクス事業本部 機械学習チームの鈴木です。

re:Invent 2023で、Amazon RedshiftクエリエディタのAmazon Q generative SQLのプレビュー提供が発表されました。

生成系AIをSQLに応用したSQL生成機能で、Amazon Redshiftクエリエディタv2からチャットが利用ができます。接続したデータベースから抽出したいことを自然言語で問い合わせすることで、生成系AIからSQLクエリが生成される機能になります。

特にプレビューの利用に参加したい方向けに、使い方のイメージや必要になった設定についてご紹介します。

Amazon Q generative SQLについて

re:Invent 2023で発表された、Amazon Redshiftクエリエディタv2向けのSQL生成機能です。

Management Guideの中に、以下のガイドが用意されています。この記事でも触れますが、単にユーザーとしてAmazon Redshiftクエリエディタv2からチャットを利用する以外にも、管理者としてgenerative SQLの設定を変更する場合の事項についても記載されていますので、ご確認ください。

記事執筆時点で米国東部 (バージニア北部)、米国西部 (オレゴン) のリージョンでパブリックプレビュー中です。チャットの言語は英語となります。

以下のAWS News Blogにも使用例があるので合わせてご確認ください。

generative SQLを使用する準備

まずはチャットを利用するにあたっての前提事項を確認していきます。

1. Redshift Serverlessの準備

今回は新しいRedshift Serverlessのリソースをバージニア北部リージョンに作成しました。

作成には、『Amazon Redshift Serverlessでクロスアカウントのデータ共有を試してみました』などで使っているいつものCloudFormationテンプレートを使用しました。

この記事にも記載しますが、長いのでトグルメニューにして隠しておきます。

CloudFormationテンプレート
AWSTemplateFormatVersion: "2010-09-09"
Description: "Redshift Serverless and VPC"
Parameters:
  Env:
    Type: "String"
    Default: "test"
  ProjectName:
    Type: "String"
  CidrBlock:
    Description: Please type the CidrBlock.
    Type: String
    Default: 192.168.0.0/22
  BaseCapacity: 
    Type: Number
    Default: 8
  EnhancedVpcRouting: 
    Type: String
    AllowedValues:
      - true
      - false
    Default: false 
  PubliclyAccessible: 
    Type: String
    AllowedValues:
      - true
      - false
    Default: true
  AdminUsername:
    Type: String
    Default: awsuser
  AdminUserPassword:
    Type: String
    Description: Must be 8-64 characters long. Must contain at least one uppercase letter, one lowercase letter and one number. Can be any printable ASCII character except “/”, ““”, or “@”.
    NoEcho: true
    MinLength: 8
    MaxLength: 64

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Sub ${CidrBlock}
      EnableDnsSupport: True
      EnableDnsHostnames: True
      InstanceTenancy: default
      Tags:
      - Key: Name
        Value: !Sub ${ProjectName}-redshiftserverless-${Env}-VPC
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
      - Key: Application
        Value:
          Ref: AWS::StackId
      - Key: Network
        Value: Public
  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId:
        Ref: VPC
      InternetGatewayId:
        Ref: InternetGateway
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    DependsOn: AttachGateway
    Properties:
      VpcId:
        Ref: VPC
      Tags:
      - Key: Name
        Value: !Sub |
          ${ProjectName}-redshiftserverless-${Env}-public-rtb
      - Key: Application
        Value:
          Ref: AWS::StackId
  PublicRoute:
    Type: AWS::EC2::Route
    DependsOn: AttachGateway
    Properties:
      RouteTableId:
        Ref: PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId:
        Ref: InternetGateway

  Subnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId:
        Ref: VPC
      AvailabilityZone: !Select [ 0, !GetAZs ]
      CidrBlock: !Select [ 0, !Cidr [ !GetAtt VPC.CidrBlock, 4, 8 ]]
  Subnet2:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId:
        Ref: VPC
      AvailabilityZone: !Select [ 1, !GetAZs ]
      CidrBlock: !Select [ 1, !Cidr [ !GetAtt VPC.CidrBlock, 4, 8 ]]
  Subnet3:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId:
        Ref: VPC
      AvailabilityZone: !Select [ 2, !GetAZs ]
      CidrBlock: !Select [ 2, !Cidr [ !GetAtt VPC.CidrBlock, 4, 8 ]]

  Subnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId:
        Ref: Subnet1
      RouteTableId:
        Ref: PublicRouteTable
  Subnet2RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId:
        Ref: Subnet2
      RouteTableId:
        Ref: PublicRouteTable
  Subnet3RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId:
        Ref: Subnet3
      RouteTableId:
        Ref: PublicRouteTable
  RedshiftServerlessSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      VpcId:
        Ref: VPC
      GroupDescription: Marker security group for Application server.
      Tags:
      - Key: Name
        Value: !Sub |
          ${ProjectName}-redshiftserverless-${Env}-sg
  RedshiftServerlessRole:
    Type: "AWS::IAM::Role"
    Properties:
      Path: "/"
      RoleName: !Sub "${ProjectName}-${Env}-redshift-role"
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - redshift.amazonaws.com
            Action: sts:AssumeRole
      MaxSessionDuration: 3600
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/AmazonAthenaFullAccess"
        - "arn:aws:iam::aws:policy/AmazonS3FullAccess"
        - "arn:aws:iam::aws:policy/AWSGlueConsoleFullAccess"
        - "arn:aws:iam::aws:policy/AmazonRedshiftAllCommandsFullAccess"
      Description: "Allows Redshift clusters to call AWS services on your behalf."
      Tags:
        - Key: "Name"
          Value: !Sub "${ProjectName}-redshiftserverless-${Env}-redshift-role"
  RedshiftServerlessWorkGroup:
    Type: AWS::RedshiftServerless::Workgroup
    Properties: 
      WorkgroupName: !Sub "${ProjectName}-${Env}-redshift-wg"
      BaseCapacity: !Ref BaseCapacity
      EnhancedVpcRouting: !Ref EnhancedVpcRouting
      NamespaceName: !Ref RedshiftServerlessNamespace
      PubliclyAccessible: !Ref PubliclyAccessible
      SecurityGroupIds: 
        - !Ref RedshiftServerlessSecurityGroup
      SubnetIds: 
        - !Ref Subnet1
        - !Ref Subnet2
        - !Ref Subnet3
  RedshiftServerlessNamespace:
    Type: AWS::RedshiftServerless::Namespace
    Properties: 
      NamespaceName: !Sub "${ProjectName}-${Env}-redshift-ns"
      AdminUsername: !Ref AdminUsername
      AdminUserPassword: !Ref AdminUserPassword
      DbName: !Sub "${ProjectName}-db"
      IamRoles: 
        - !GetAtt RedshiftServerlessRole.Arn

このテンプレートをCloudFormationからデプロイしました。

2. サンプルのデータベースの作成

作成されたRedshift Serverlessインスタンスに、Redshift query editor v2で、awsuserスーパーユーザーで接続し、tpchサンプルデータベースを作成しました。

以下のようにサンプルデータベースとサンプルのノートブックが作成されました。

サンプルデータベース

上の画像で表示されているGenerative SQLというボタンを押すとチャットインターフェースが現れるイメージです。チャットはノートブックが対象となるようでした。

3. Generative SQLの有効化

早速チャットをしてみたいところですが、Generative SQLを設定から有効化しておく必要がありました。

クエリエディタv2の左下にある歯車マークを押すと、Generative SQL settingsがあるのでクリックしました。

Generative SQL settings

以下のように設定のポップアップが出るので、Generative SQLにチェックを入れてSaveを押しました。

設定ポップアップ

この設定の後にGenerative SQLを押すとチャットへの入力ができるようになりました。

チャット用UI

ちなみに有効化しないままGenerative SQLを押すと、このように有効化を促す表示がされました。

有効化を促す表示

SQLを生成してみる

準備ができたので、実際にSQLを生成して使い心地を確認してみました。

1. 単純な集約

まずは一つのテーブルで完結するものを試してみました。

以下のように入力してみました。

Which mktsegments are top 5 in customer table of tpch?

以下のようにSQLが生成されました。Add to notebookを押すとノートブックにこのSQLが追加されました。

セグメントごとの数え上げ

ここまでで特にデータベースになんのテーブルがあってという情報は与えていません。クエリエディタの接続でどのデータベースかを指定する必要はありますが、そのデータベース内であれば自動で認識してくれるようでした。

ノートブックで実行すると一発で欲しいものが得られました。

実行結果1

2. テーブルの結合が必要なもの

もう少し難しいものもチャレンジしてみようということで、以下の質問もしてみました。

How many nations in each region?

以下のように結合を使ったクエリが生成されました。

結合が必要な質問

こちらもエラーなく実行できました。すごい。

実行結果2

感想

分析したいことをチャットで指示すると、それに対応したSQLを生成してくれました。

複雑な質問ではないため生成されたSQLもそこまで難しいものではなかったので、実際独自のデータで開発環境などで検証して頂くのが良さそうですが、少なくともこのレベルの質問であれば一発でエラーのないSQLを生成でき、期待通りの結果が得られました。

ETL用や複雑なアドホック分析用のクエリを生成してもらう場合、チャットで依頼する内容も複雑になるため、多少の手直しが必要になると思います。この場合、Add to notebookを押すとノートブックにすぐコピーできるため、とても使いやすいと思います。

開発のときには、仕様が既に自然言語のテキストで決まっていたり、頭の中で思いついた分析ロジックがあったりすることが多いですが、SQLで表現するためにはどうしてももう一息頑張ってロジックをSQLに変換する必要があります。このような場合に、SQLを使った分析に慣れている方であっても、想定しているものをGenerative SQLが書き出してくれたり、思っているものに近いSQLを出してくれて手直しすれば完成したりすると、とても作業が効率化され、嬉しい機能だと思います。

もちろん、この機能によりSQLに慣れていない方でもテキストからSQLを作って分析できるもの大きなポイントですね。

最後に

re:Invent 2023でアナウンスされた、プレビュー提供のAmazon Redshiftクエリエディタv2向けのAmazon Q generative SQLのご紹介でした。

参考になりましたら幸いです。