返回首页

gbase数据、南大通用产品文档:GBase8a

更新日期:2024年09月11日

使用GBase C API 执行SQL 语句
/*打印表中的数据,示例demo_1,demo_2,demo_3 调用此函数*/
void print_table(GBASE* gbase, char* table_name)
{
GBASE_RES* res = NULL;
GBASE_FIELD* fields = NULL;
GBASE_ROW row;
unsigned int num_fields;
char sql_select[500] = "select * from ";
int i=0;

while(table_name[i]){sql_select[14+i] = table_name[i]; i++;}
sql_select[14+i] = '\0';
if(gbase_query(gbase, sql_select))
{
printf("%d\t%s\n", gbase_errno(gbase),
gbase_error(gbase));
exit(0);
}
res = gbase_store_result(gbase);
num_fields = gbase_num_fields(res);
while(fields = gbase_fetch_field(res))
{
printf("|%s\t", fields->name);



GBase 8a 程序员手册C API 篇
南大通用数据技术股份有限公司

- 71 -
}
printf("|\n");
for(i=0;i{
printf("--------");
}
printf("\n");
while((row = gbase_fetch_row(res)) != NULL)
{
for(i=0; i < num_fields; i++)
{
printf("|%s\t", row[i]);
}
printf("|\n");
}
gbase_free_result(res);
}
/*
使用sql 文创建表,并进行数据增、删、查、改操作
*/
void demo_1(void)
{
GBASE* gbase=NULL;
const char* sql_drop_table = "drop table if exists g_demo1";
const char* sql_create_table = "create table g_demo1(id int,
name varchar(20))";
const char* insert_mode = "insert into g_demo1(id,
name)values(%d, '%s')";
int id[NUM_INSERT];
char name[NUM_INSERT][20];
char sql_insert[200];
const char* delete_mode = "delete from g_demo1 where id=%d";
char sql_delete[200];
const char* update_mode = "update g_demo1 set name='udpate'
where id=%d";
char sql_update[200];

GBase 8a 程序员手册C API 篇


- 72 -

南大通用数据技术股份有限公司
const char* sql_select = "select * from g_demo1";
GBASE_RES* res = NULL;
GBASE_FIELD* fields = NULL;
GBASE_ROW row;

unsigned int i = 0;
unsigned int num_fields = 0;

/*初始化GBASE 结构体*/
if(!(gbase = gbase_init(0)))
{
fprintf(stderr, "不能初始化GBASE 结构体!\n");
exit(1);
}

/*数据库连接*/
if(!gbase_real_connect(gbase, host, user, passwd, db, port,
NULL, 0))
{
fprintf(stderr, "\n%s\n", gbase_error(gbase));
exit(1);
}
gbase->reconnect = 1;

/*在数据库中创建表*/
if(gbase_query(gbase, sql_drop_table))
{
fprintf(stderr, "%s", gbase_error(gbase));
exit(1);
}
if(gbase_query(gbase, sql_create_table))
{
fprintf(stderr, "\n%s\n", gbase_error(gbase));
exit(1);
}
/*向数据库表中插入数据*/
for(i=0; i


GBase 8a 程序员手册C API 篇
南大通用数据技术股份有限公司

- 73 -
{
id[i] = i;
sprintf(name[i], "name_%d", i);
}
for(i=0; i{
sprintf(sql_insert, insert_mode, id[i], name[i]);
if(gbase_query(gbase, sql_insert))
{
fprintf(stderr, "\n%s\n", gbase_error(gbase));
exit(1);
}
}
/*从数据库表中选择出数据,并显示*/
if(gbase_query(gbase, sql_select))
{
fprintf(stderr, "\n%s\n", gbase_error(gbase));
exit(1);
}
res = gbase_store_result(gbase);
printf("插入操作后表的内容\n");
if(res)
{
num_fields = gbase_num_fields(res);
while(fields = gbase_fetch_field(res))
{
printf("\t| %s ", fields->name);
}
printf("\t|\n");
while((row = gbase_fetch_row(res)) != NULL)
{
for(i=0; i < num_fields; i++)
{
printf("\t| %s ", row[i]);
}
printf("\t|\n");
}

GBase 8a 程序员手册C API 篇


- 74 -

南大通用数据技术股份有限公司
}

/*更新数据库表中数据*/
sprintf(sql_update, update_mode, id[0]);
if(gbase_query(gbase, sql_update))
{
fprintf(stderr, "\n%s\n", gbase_error(gbase));
exit(1);
}
printf("更新操作后表的内容\n");
print_table(gbase, "g_demo1");

/*删除数据库表中数据*/
sprintf(sql_delete, delete_mode, id[1]);
if(gbase_query(gbase, sql_delete))
{
fprintf(stderr, "\n%s\n", gbase_error(gbase));
exit(1);
}
printf("删除操作后表的内容\n");
print_table(gbase, "g_demo1");
/*释放结果集*/
gbase_free_result(res);
/*释放数据库连接句柄*/
gbase_close(gbase);
}

/*
使用预处理语句进行数据插入和选择操作
*/
void demo_2(void)
{
GBASE* gbase=NULL;
GBASE_STMT* stmt;
GBASE_BIND bind[2];




GBase 8a 程序员手册C API 篇
南大通用数据技术股份有限公司

- 75 -
const char* sql_drop_table = "drop table if exists g_demo2";
const char* sql_create_table = "create table g_demo2(id int,
name varchar(20))";
const char* insert_mode = "insert into g_demo2(id,
name)values(?, ?)";
int in_id[NUM_INSERT];
char in_name[NUM_INSERT][20];
const char* update_mode = "update g_demo2 set name='update'
where id=?";
const char* delete_mode = "delete from g_demo2 where id=?";
const char* select_mode = "select id, name from g_demo2";
int out_id[NUM_INSERT];
char out_name[NUM_INSERT][20];

unsigned int i = 0;
int temp = 0;
unsigned int num_fields = 0;

/*初始化GBASE 结构体*/
if(!(gbase = gbase_init(0)))
{
fprintf(stderr, "不能初始化GBASE 结构体!\n");
exit(1);
}
/*数据库连接*/
if(!gbase_real_connect(gbase, host, user, passwd, db, port,
NULL, 0))
{
fprintf(stderr, "\n%s\n", gbase_error(gbase));
exit(1);

}
gbase->reconnect = 1;
/*在数据库中创建表*/
if(gbase_query(gbase, sql_drop_table))
{
fprintf(stderr, "%s", gbase_error(gbase));
exit(1);

GBase 8a 程序员手册C API 篇


- 76 -

南大通用数据技术股份有限公司
}
if(gbase_query(gbase, sql_create_table))
{
fprintf(stderr, "\n%s\n", gbase_error(gbase));
exit(1);
}
/*向数据库表中插入数据*/
for(i=0; i{
in_id[i] = i;
sprintf(in_name[i], "name_%d", i);
}
if(!(stmt = gbase_stmt_init(gbase)))
{
fprintf(stderr, "\n%s\n", gbase_stmt_error(stmt));
exit(1);
}
if(gbase_stmt_prepare(stmt, insert_mode,
strlen(insert_mode)))
{
fprintf(stderr, "\n%s\n", gbase_stmt_error(stmt));
exit(1);
}

memset(bind, 0, sizeof(bind));

bind[0].buffer_type = GBASE_TYPE_LONG;
bind[1].buffer_type = GBASE_TYPE_STRING;
bind[1].buffer_length = 20;
printf("插入操作后表的内容\n");
for(i=0; i{
bind[0].buffer = (void*)∈_id[i];
bind[1].buffer = (void*)in_name[i];

if(gbase_stmt_bind_param(stmt, bind))
{



GBase 8a 程序员手册C API 篇
南大通用数据技术股份有限公司

- 77 -
fprintf(stderr, "\n%s\n", gbase_stmt_error(stmt));
exit(1);
}
if(gbase_stmt_execute(stmt))
{
fprintf(stderr, "\n%s\n", gbase_stmt_error(stmt));
exit(1);
}
}
/*从数据库表中选择数据*/
if(gbase_stmt_prepare(stmt, select_mode,
strlen(select_mode)))
{
fprintf(stderr, "\n%s'n", gbase_stmt_error(stmt));
exit(1);
}
memset(bind, 0, sizeof(bind));

bind[0].buffer_type = GBASE_TYPE_LONG;
bind[1].buffer_type = GBASE_TYPE_STRING;
bind[1].buffer_length = 20;

if(gbase_stmt_execute(stmt))
{
fprintf(stderr, "\n%s\n", gbase_stmt_error(stmt));
exit(1);
}

for(i=0; i{
bind[0].buffer = (void*)&out_id[i];
bind[1].buffer = (void*)out_name[i];

if(gbase_stmt_bind_result(stmt, bind))
{
fprintf(stderr, "\n%s\n", gbase_stmt_error(stmt));
exit(1);

GBase 8a 程序员手册C API 篇


- 78 -

南大通用数据技术股份有限公司
}
if(!gbase_stmt_fetch(stmt))
{
printf("\t|%d\t|%s\t|\n", out_id[i] , out_name[i]);
}
else
{
fprintf(stderr, "\n%s\n", gbase_stmt_error(stmt));
exit(1);
}
}
/*更新数据库表中数据*/
if(gbase_stmt_prepare(stmt, update_mode,
strlen(update_mode)))
{
fprintf(stderr, "\n%s'n", gbase_stmt_error(stmt));
exit(1);
}
memset(bind, 0, sizeof(bind));

temp = 0;
bind[0].buffer_type = GBASE_TYPE_LONG;
bind[0].buffer = (void*)&temp

if(gbase_stmt_bind_param(stmt, bind))
{
fprintf(stderr, "\n%s\n", gbase_stmt_error(stmt));
exit(1);
}

if(gbase_stmt_execute(stmt))
{
fprintf(stderr, "\n%s\n", gbase_stmt_error(stmt));
exit(1);
}
printf("更新操作后表的内容\n");
print_table(gbase, "g_demo2");



GBase 8a 程序员手册C API 篇
南大通用数据技术股份有限公司

- 79 -
/*删除数据库表中数据*/
if(gbase_stmt_prepare(stmt, delete_mode,
strlen(delete_mode)))
{
fprintf(stderr, "\n%s'n", gbase_stmt_error(stmt));
exit(1);
}
memset(bind, 0, sizeof(bind));

temp = 1;
bind[0].buffer_type = GBASE_TYPE_LONG;
bind[0].buffer = (void*)&temp

if(gbase_stmt_bind_param(stmt, bind))
{
fprintf(stderr, "\n%s\n", gbase_stmt_error(stmt));
exit(1);
}

if(gbase_stmt_execute(stmt))
{
fprintf(stderr, "\n%s\n", gbase_stmt_error(stmt));
exit(1);
}
printf("删除操作后表的内容\n");
print_table(gbase, "g_demo2");

/*关闭STMT 语句句柄*/
if(gbase_stmt_close(stmt))
{
fprintf(stderr, "%s\n", gbase_stmt_error(stmt));
exit(1);
}
/*释放数据库连接句柄*/
gbase_close(gbase);
}

GBase 8a 程序员手册C API 篇


- 80 -

南大通用数据技术股份有限公司

算子级调优
算子级调优介绍
一个查询语句要经过多个算子步骤才会输出最终的结果。
由于个别算子耗时过长导致整
体查询性能下降的情况比较常见。这些算子是整个查询的瓶颈算子。通用的优化手段是

GBase 8c V5 开发者手册
南大通用数据技术股份有限公司
558
EXPLAIN ANALYZE/PERFORMANCE 命令查看执行过程的瓶颈算子,
然后进行针对性优化。
如下面的执行过程信息中,Hashagg 算子的执行时间占总时间的:(51016-13535)/ 56476
≈66%,此处Hashagg 算子就是这个查询的瓶颈算子,在进行性能优化时应当优先考虑此算
子的优化。
算子级调优示例
示例1:
基表扫描时,
对于点查或者范围扫描等过滤大量数据的查询,
如果使用SeqScan
全表扫描会比较耗时,
可以在条件列上建立索引选择IndexScan 进行索引扫描提升扫描效率。
gsql=#
explain (analyze on, costs off) select * from store_sales where ss_sold_date_sk =
2450944;
id |
operation
|
A-time
| A-rows | Peak Memory
|
A-width
----+--------------------------------+---------------------+--------+--------------+---------
1 | ->
Streaming (type: GATHER)
| 3666.020
|
3360 | 195KB
|
2 |
->
Seq Scan on store_sales | [3594.611,3594.611] |
3360 | [34KB, 34KB] |
(2 rows)
Predicate Information (identified by plan id)
-----------------------------------------------
2 --Seq Scan on store_sales
Filter: (ss_sold_date_sk = 2450944)
Rows Removed by Filter: 4968936
gsql=#
create index idx on store_sales_row(ss_sold_date_sk);
CREATE INDEX
gsql=#
explain (analyze on, costs off) select * from store_sales_row where ss_sold_date_sk =
2450944;
id |
operation
|
A-time
| A-rows |
Peak Memory
| A-width
----+------------------------------------------------+-----------------+--------+--------------+----------
1 | ->
Streaming (type: GATHER)
| 81.524
|
3360 |
195KB
|
2 |
->
Index Scan using idx on store_sales_row | [13.352,13.352] |
3360 | [34KB,
34KB] |
(2 rows)
上述例子中,全表扫描返回3360 条数据,过滤掉大量数据,在ss_sold_date_sk 列上建
立索引后,使用IndexScan 扫描效率显著提高,从3.6 秒提升到13 毫秒。

GBase 8c V5 开发者手册
南大通用数据技术股份有限公司
559
示例2:
如果从执行计划中看,
两表join 选择了NestLoop,
而实际行数比较大时,
NestLoop
Join 可能执行比较慢。如下的例子中NestLoop 耗时181 秒,如果设置参数
enable_mergejoin=off 关掉Merge Join,同时设置参数enable_nestloop=off 关掉NestLoop,让
优化器选择HashJoin,则Join 耗时提升至200 多毫秒。
示例3:
通常情况下Agg 选择HashAgg 性能较好,
如果大结果集选择了Sort+GroupAgg,
则需要设置enable_sort=off,HashAgg 耗时明显优于Sort+GroupAgg。

CREATE
SCHEMA 块还将行添加至 systabauth 系统目录表。这些行对应于对 customer
和 california 表授予的用户特权,如以下示例所示。

GBase 8s SQL 指南:参考
南大通用数据技术股份有限公司 - 10 -


grantor
grantee
tabid
tabauth
maryl
public
101
su-idx--
maryl
cathl
101
SU-IDXAR
maryl
nhowe
101
--*-----

maryl
102
SU-ID---

tabauth 列指定授予用户的对 customer 和 california 表的表级别特权。此列使用
8 字节模式(如 s(选择)、u(更新)、*(列级别特权)、i(插入)、d(删除)、x(索
引)

a
(改变)
和 r
(引用)

来标识特权的类型。
在此示例中,
用户 nhowe 具有对 customer
表的列级别特权。连字符 (-) 表示未向用户授予 tabauth 值中由连字符占据其位置的特
权。
如果 tabauth 特权代码是大写的
(例如,
表示 Select 的 S)

那么用户具有此特权,
并可将该特权授予他人;但是,如果特权代码是小写的(例如:表示 Select 的 s),那
么用户不能将该特权授予他人。