ASE Sybaseのデータ使用量の調査方法

# デバイス
### sp_helpdevice

**`sp_helpdevice`**
Descriptionの欄にサイズと空きが表示される。

**`sp_helpdevice DEVICENAME`**
引数にデバイス名を指定するとそのデバイスを使用しているDBの名前も確認可能。


# データベース

### sp_helpdb
**`sp_helpdb`**
引数なしだと全てのDBのサマリ情報が出力。

**`sp_helpdb DBNAME`**
DB名を引数に指定すると空き容量を含むそのDBの詳細情報が確認出来る。
２つめのブロック（device_fragments）にセグメント毎にサイズと空き容量が表示され、DB単位で見る時はdevice_fragmentsの単位でグルーピングして合計する。
ログセグメントは空き容量が表示されない。

### SQL
下記のSQLでデータセグメント、ログセグメント両方のデータ使用量と使用率が確認可能。
実行時は`use DBNAME`で対象のDBに入って操作する必要あり。
```
select
	 db_name(d.dbid) as db_name
	,'data' as segment_type
	,convert(numeric(12,1), ceiling(sum(u.size/1048576.*@@maxpagesize))) as size_mb
	,convert(numeric(12,1), round(sum(size - curunreservedpgs(u.dbid, u.lstart, u.unreservedpgs))/1048576.*@@maxpagesize ,1)) as used_mb
	,convert(numeric(4,1),  round(100 * (1 - 1.0 * sum(curunreservedpgs(u.dbid, u.lstart, u.unreservedpgs)) / sum(u.size)) ,1)) as used_pct
from
	master..sysdatabases d,
	master..sysusages u
where
		u.dbid = d.dbid
	and d.status not in (256,4096)
	and u.segmap != 4
group by d.dbid
union
select
	 db_name(d.dbid) as db_name
	,'log' as segment_type
	,convert(numeric(12,1), ceiling(sum(u.size/1048576.*@@maxpagesize))) as size_mb
    ,convert(numeric(12,1), round(sum(u.size/1048576.*@@maxpagesize) - lct_admin("logsegment_freepages",d.dbid)/1048576.*@@maxpagesize ,1)) as used_mb
    ,convert(numeric(4,1),  round((100 * (1 - 1.0 * (lct_admin("logsegment_freepages",d.dbid) - 1.0 * lct_admin("reserved_for_rollbacks",d.dbid)) / sum(case when u.segmap in (4, 7) then u.size end))) ,1)) as used_pct
from
	master..sysdatabases d,
	master..sysusages u
where
		u.dbid = d.dbid
	and d.status not in (256,4096)
	and u.segmap = 4
group by d.dbid
order by db_name(d.dbid), segment_type
```
<details><summary>実行結果</summary>

```
db_name                        segment_type size_mb         used_mb         used_pct
------------------------------ ------------ --------------- --------------- --------
SMP                            data                 47508.0         45180.8     99.3
SMP                            log                  10360.0            54.1      0.4
master                         data                   300.0            51.4     15.9
model                          data                    48.0            18.7     56.9
saptempdb                      data                  8192.0            48.0      0.6
saptools                       data                  8192.0          3811.0     77.2
saptools                       log                   1024.0             4.0      0.5
sybmgmtdb                      data                   512.0           100.4     17.1
sybmgmtdb                      log                    512.0             2.1      0.4
sybsecurity                    data                   200.0            14.3      7.8
sybsecurity                    log                     16.0             0.1      0.7
sybsystemdb                    data                    72.0            12.9     19.6
sybsystemprocs                 data                   512.0           145.6     48.3
tempdb                         data                  4096.0            10.2      0.4
```
</details>

参考
https://dhmarciano.com/node/19

# ログセグメント
実行時は`use DBNAME`で対象のDBに入って操作する必要あり。

### sp_helpsegment
**`sp_helpsegment logsegment`**
ログセグメント名を引数に指定。

### SQL
```
select
    convert(char(16), db_name(d.dbid))
        + "|Log_Total_MB=" + convert(char(9), ceiling(sum(case when u.segmap = 4 then u.size/1048576.*@@maxpagesize end)))
        + "|Free_MB="
        + convert(char(12),
    (convert(numeric(8,1),
        (lct_admin("logsegment_freepages",d.dbid) - 1.0 * lct_admin("reserved_for_rollbacks",d.dbid)) /1048576.*@@maxpagesize)))
        + "|Used="
        + rtrim(convert(char(7),
    (convert(numeric(12,2),
    (100 * (1 - 1.0 * (lct_admin("logsegment_freepages",d.dbid) - 1.0 * lct_admin("reserved_for_rollbacks",d.dbid)) / sum(case when u.segmap in (4, 7) then u.size end))))))) + "%"
from
    master..sysdatabases d,
    master..sysusages u
where
        u.dbid = d.dbid
    and d.status not in (256,4096)
group by d.dbid
having (sum(case when u.segmap = 4 then u.size/1048576.*@@maxpagesize end)) != NULL
order by db_name(d.dbid)
```

参考：
https://answers.sap.com/questions/12742524/sybase-saptools-log-doesn%27t-clear.html


# テーブル

### sp_spaceusage
`sp_spaceusage 'display summary ', 'table', 'TABLENAME'`

- sp_spaceusageでもテーブル毎の情報が取得可能。
- 第一引数に'display summary'を指定するとテーブル、インデックス両方の情報が取れる。
- その他にも色々な情報が取れる模様。詳細はマニュアル参照。
[SAP Adaptive Server Enterprise > Reference Manual: Procedures > System Stored Procedures > sp_spaceusage](https://help.sap.com/docs/SAP_ASE/fbeb8a16c28d4140a01bd3b5821e0cd5/ab7e8712bc2b1014ab32f638aea2c944.html?version=16.0.2.0&locale=en-US)

### sp_help
**`sp_help TABLENAME`**
参考：[SAP Adaptive Server Enterprise>Reference Manual: Procedures>System Stored Procedures](https://help.sap.com/docs/SAP_ASE/29a04b8081884fb5b715fe4aa1ab4ad2/ab4d2206bc2b1014a05fad9b806e474a.html?locale=en-US&version=16.0.4.0)

### SQL
```
select
     convert(varchar(30),o.name)  AS table_name
    ,row_count(db_id(), o.id)     AS row_count
    ,data_pages(db_id(), o.id, 0) AS pages
    ,data_pages(db_id(), o.id, 0) * (@@maxpagesize/1024) AS size_kb
from sysobjects o
where type = 'U'
order by table_name
```
### sp_spaceused
`sp_spaceused TABLENAME, 1`
- テーブル毎の情報が取得する場合は sp_spaceusage が使用可能。
- テーブルに紐づくインデックスの情報も取得可能。
- 詳細はマニュアル参照。
[SAP Adaptive Server Enterprise | Reference Manual - sp_spaceused](https://help.sap.com/docs/SAP_ASE/fbeb8a16c28d4140a01bd3b5821e0cd5/ab7f0c5abc2b1014a6e8acf70b6f5aea.html?version=16.0.2.0&locale=en-US)