SELECT

通过SELECT语句可以查询一个或多个表格中的行数据。

说明

与RDBMS不同,Lindorm的SELECT语句仅支持扁平化的查询。

语法

SELECT [hint_clause] ( select_clause | '*' )
    FROM table_name
    [force index(index_name)]
    [ WHERE where_clause ]
    [ ORDER BY ordering_clause ]
    [ LIMIT integer ] | [LIMIT integer, integer]
    [`ALLOW FILTERING`]
select_clause    ::=  selector [ AS identifier ] ( ',' selector [ AS identifier ] )
selector         ::=  column_name
                      | term
                      | function_name '(' [ selector ( ',' selector )* ] ')'
                      | COUNT '(' '*' ')'
where_clause     ::=  relation ( AND|OR relation )*
relation         ::=  column_name operator term
                      '(' column_name ( ',' column_name )* ')' operator tuple_literal
operator         ::=  '=' | '<' | '>' | '<=' | '>=' | '!=' | IN | IS NOT? NULL
ordering_clause  ::=  column_name [ ASC | DESC ] ( ',' column_name [ ASC | DESC ] )*

hint_clause::=/*+hint_items*/
hint_items::=hint_item(','hint_item)*
hint_item::=identifier('('hint_option(','hint_option)*')')
hint_option::=expression

参数说明

SELECT语法中部分参数说明如下:

  • 执行SELECT语句时如果您需要强制选择某条索引,请在查询语句后使用force index(index_name)

  • LIMIT子句用于分页查询。LIMIT后只跟一个数字,表示LIMIT限制。如果跟两个由英文逗号(,)分隔的数字,表示OFFSET和LIMIT条数。

    重要

    LIMIT子句指定OFFSET后,分页查询仍然会检索OFFSET跳过的数据。为避免查询负载过大,建议您将OFFSET的值设置在5000以内。

  • 在SELECT语句末尾添加ALLOW FILTERING,可以强制执行低效查询操作。当执行SELECT语句被Lindorm宽表引擎识别为低效查询时,为了避免这类查询语句给Lindorm带来性能稳定性风险,Lindorm宽表引擎默认不允许执行该类查询,同时会抛出异常。例如Lindorm数据库中存在一张表dt,执行SELECT * FROM dt WHERE nonPK=100;查询语句,会返回以下异常报错。如果查询语句为低效查询语句,解决方法请参见常见问题

    DoNotRetryIOException: Detect inefficient query: SELECT * FROM dt WHERE nonPK=100 supportEmptyResult true. This query may be a full table scan and thus may have unpredictable performance.
  • Hint的使用请参见HINT简介

示例

//简单查询操作

SELECT * FROM dt;            //选择全部列
SELECT c1,c2 FROM dt;                   //选择部分列
SELECT * FROM dt LIMIT 10;
SELECT * FROM dt WHERE pk = 10;
SELECT * FROM dt WHERE pk > 10 LIMIT 5, 20;           //跳过5行,最多返回20行
SELECT * FROM dt WHERE pk > 10 LIMIT 20 OFFSET 5;      //等价于limit 5,20
SELECT c1 FROM dt WHERE pk > 10;
SELECT c1 AS xx FROM dt WHERE pk > 10;

//聚合操作

SELECT count(*) FROM dt;
SELECT count(c1) FROM dt;
SELECT sum(c2) FROM dt;
SELECT sum(c2), AVG(c2),MIN(c2),MAX(c2) FROM dt;

//where条件中is null等用法

SELECT c1, c2 FROM dt WHERE (c1>1 OR (c2>0 AND c7 is null)) 
AND c3 <>1.0 AND c6 is not null;

//别名用法
SELECT count(*) AS countRow FROM dt;
SELECT c1 AS testC FROM t1 WHERE c1 = '2';

//in用法
SELECT * FROM dt WHERE dt in ('a', 'b');

//强制执行低效查询语句
SELECT * FROM dt WHERE nonPK=100 ALLOW FILTERING;
            

常见问题

  • Q:什么情况下,查询语句被认为是低效查询语句?

    A:如果SELECT查询的条件同时满足下列三个条件,则该查询被认为是低效查询。

    • WHERE语句中没有指定表的第一个主键的上下界。

    • WHERE语句中没有指定索引表中第一个索引列的上下界。

    • WHERE语句中存在非第一个主键(或非第一个索引列)的条件。

  • Q:如果查询语句为低效查询语句,应该怎么解决?

    A:解决方法有以下四种。

    • 在查询语句末尾增加ALLOW FILTERING,如下语句,表示跳过该检查,强制执行低效查询操作。

      SELECT * FROM dt WHERE nonPK=100 ALLOW FILTERING;
    • WHERE语句中增加表的主键条件。

    • 修改表的主键设计,避免大查询,具体详情请参见如何设计宽表主键

    • 使用高性能原生二级索引,具体详情请参见二级索引

阿里云首页 云原生多模数据库Lindorm 相关技术圈