11## Some useful SQL queries for Synapse Admins
22
33## Size of full matrix db
4- ` SELECT pg_size_pretty( pg_database_size( 'matrix' ) ); `
4+ ``` sql
5+ SELECT pg_size_pretty( pg_database_size( ' matrix' ) );
6+ ```
7+
58### Result example:
69```
710pg_size_pretty
811----------------
912 6420 MB
1013(1 row)
1114```
12- ## Show top 20 larger rooms by state events count
13- ``` sql
14- SELECT r .name , s .room_id , s .current_state_events
15- FROM room_stats_current s
16- LEFT JOIN room_stats_state r USING (room_id)
17- ORDER BY current_state_events DESC
18- LIMIT 20 ;
19- ```
20-
21- and by state_group_events count:
22- ``` sql
23- SELECT rss .name , s .room_id , count (s .room_id ) FROM state_groups_state s
24- LEFT JOIN room_stats_state rss USING (room_id)
25- GROUP BY s .room_id , rss .name
26- ORDER BY count (s .room_id ) DESC
27- LIMIT 20 ;
28- ```
29- plus same, but with join removed for performance reasons:
30- ``` sql
31- SELECT s .room_id , count (s .room_id ) FROM state_groups_state s
32- GROUP BY s .room_id
33- ORDER BY count (s .room_id ) DESC
34- LIMIT 20 ;
35- ```
3615
3716## Show top 20 larger tables by row count
3817``` sql
39- SELECT relname, n_live_tup as rows
40- FROM pg_stat_user_tables
18+ SELECT relname, n_live_tup AS " rows"
19+ FROM pg_stat_user_tables
4120 ORDER BY n_live_tup DESC
4221 LIMIT 20 ;
4322```
44- This query is quick, but may be very approximate, for exact number of rows use ` SELECT COUNT(*) FROM <table_name> ` .
23+ This query is quick, but may be very approximate, for exact number of rows use:
24+ ``` sql
25+ SELECT COUNT (* ) FROM < table_name> ;
26+ ```
27+
4528### Result example:
4629```
4730state_groups_state - 161687170
@@ -66,46 +49,19 @@ device_lists_stream - 326903
6649user_directory_search - 316433
6750```
6851
69- ## Show top 20 rooms by new events count in last 1 day:
70- ``` sql
71- SELECT e .room_id , r .name , COUNT (e .event_id ) cnt FROM events e
72- LEFT JOIN room_stats_state r USING (room_id)
73- WHERE e .origin_server_ts >= DATE_PART(' epoch' , NOW() - INTERVAL ' 1 day' ) * 1000 GROUP BY e .room_id , r .name ORDER BY cnt DESC LIMIT 20 ;
74- ```
75-
76- ## Show top 20 users on homeserver by sent events (messages) at last month:
77- ``` sql
78- SELECT user_id, SUM (total_events)
79- FROM user_stats_historical
80- WHERE TO_TIMESTAMP(end_ts/ 1000 ) AT TIME ZONE ' UTC' > date_trunc(' day' , now() - interval ' 1 month' )
81- GROUP BY user_id
82- ORDER BY SUM (total_events) DESC
83- LIMIT 20 ;
84- ```
85-
86- ## Show last 100 messages from needed user, with room names:
87- ``` sql
88- SELECT e .room_id , r .name , e .event_id , e .type , e .content , j .json FROM events e
89- LEFT JOIN event_json j USING (room_id)
90- LEFT JOIN room_stats_state r USING (room_id)
91- WHERE sender = ' @LOGIN:example.com'
92- AND e .type = ' m.room.message'
93- ORDER BY stream_ordering DESC
94- LIMIT 100 ;
95- ```
96-
9752## Show top 20 larger tables by storage size
9853``` sql
9954SELECT nspname || ' .' || relname AS " relation" ,
100- pg_size_pretty(pg_total_relation_size(C .oid )) AS " total_size"
101- FROM pg_class C
102- LEFT JOIN pg_namespace N ON (N .oid = C .relnamespace )
55+ pg_size_pretty(pg_total_relation_size(c .oid )) AS " total_size"
56+ FROM pg_class c
57+ LEFT JOIN pg_namespace n ON (n .oid = c .relnamespace )
10358 WHERE nspname NOT IN (' pg_catalog' , ' information_schema' )
104- AND C .relkind <> ' i'
59+ AND c .relkind <> ' i'
10560 AND nspname !~ ' ^pg_toast'
106- ORDER BY pg_total_relation_size(C .oid ) DESC
61+ ORDER BY pg_total_relation_size(c .oid ) DESC
10762 LIMIT 20 ;
10863```
64+
10965### Result example:
11066```
11167public.state_groups_state - 27 GB
@@ -130,8 +86,93 @@ public.device_lists_remote_cache - 124 MB
13086public.state_group_edges - 122 MB
13187```
13288
89+ ## Show top 20 larger rooms by state events count
90+ You get the same information when you use the
91+ [ admin API] ( ../../admin_api/rooms.md#list-room-api )
92+ and set parameter ` order_by=state_events ` .
93+
94+ ``` sql
95+ SELECT r .name , s .room_id , s .current_state_events
96+ FROM room_stats_current s
97+ LEFT JOIN room_stats_state r USING (room_id)
98+ ORDER BY current_state_events DESC
99+ LIMIT 20 ;
100+ ```
101+
102+ and by state_group_events count:
103+ ``` sql
104+ SELECT rss .name , s .room_id , COUNT (s .room_id )
105+ FROM state_groups_state s
106+ LEFT JOIN room_stats_state rss USING (room_id)
107+ GROUP BY s .room_id , rss .name
108+ ORDER BY COUNT (s .room_id ) DESC
109+ LIMIT 20 ;
110+ ```
111+
112+ plus same, but with join removed for performance reasons:
113+ ``` sql
114+ SELECT s .room_id , COUNT (s .room_id )
115+ FROM state_groups_state s
116+ GROUP BY s .room_id
117+ ORDER BY COUNT (s .room_id ) DESC
118+ LIMIT 20 ;
119+ ```
120+
121+ ## Show top 20 rooms by new events count in last 1 day:
122+ ``` sql
123+ SELECT e .room_id , r .name , COUNT (e .event_id ) cnt
124+ FROM events e
125+ LEFT JOIN room_stats_state r USING (room_id)
126+ WHERE e .origin_server_ts >= DATE_PART(' epoch' , NOW() - INTERVAL ' 1 day' ) * 1000
127+ GROUP BY e .room_id , r .name
128+ ORDER BY cnt DESC
129+ LIMIT 20 ;
130+ ```
131+
132+ ## Show top 20 users on homeserver by sent events (messages) at last month:
133+ Caution. This query does not use any indexes, can be slow and create load on the database.
134+ ``` sql
135+ SELECT COUNT (* ), sender
136+ FROM events
137+ WHERE (type = ' m.room.encrypted' OR type = ' m.room.message' )
138+ AND origin_server_ts >= DATE_PART(' epoch' , NOW() - INTERVAL ' 1 month' ) * 1000
139+ GROUP BY sender
140+ ORDER BY COUNT (* ) DESC
141+ LIMIT 20 ;
142+ ```
143+
144+ ## Show last 100 messages from needed user, with room names:
145+ ``` sql
146+ SELECT e .room_id , r .name , e .event_id , e .type , e .content , j .json
147+ FROM events e
148+ LEFT JOIN event_json j USING (room_id)
149+ LEFT JOIN room_stats_state r USING (room_id)
150+ WHERE sender = ' @LOGIN:example.com'
151+ AND e .type = ' m.room.message'
152+ ORDER BY stream_ordering DESC
153+ LIMIT 100 ;
154+ ```
155+
133156## Show rooms with names, sorted by events in this rooms
134- ` echo "select event_json.room_id,room_stats_state.name from event_json,room_stats_state where room_stats_state.room_id=event_json.room_id" | psql synapse | sort | uniq -c | sort -n `
157+
158+ ** Sort and order with bash**
159+ ``` bash
160+ echo " SELECT event_json.room_id, room_stats_state.name FROM event_json, room_stats_state \
161+ WHERE room_stats_state.room_id = event_json.room_id" | psql -d synapse -h localhost -U synapse_user -t \
162+ | sort | uniq -c | sort -n
163+ ```
164+ Documentation for ` psql ` command line parameters: https://www.postgresql.org/docs/current/app-psql.html
165+
166+ ** Sort and order with SQL**
167+ ``` sql
168+ SELECT COUNT (* ), event_json .room_id , room_stats_state .name
169+ FROM event_json, room_stats_state
170+ WHERE room_stats_state .room_id = event_json .room_id
171+ GROUP BY event_json .room_id , room_stats_state .name
172+ ORDER BY COUNT (* ) DESC
173+ LIMIT 50 ;
174+ ```
175+
135176### Result example:
136177```
137178 9459 !FPUfgzXYWTKgIrwKxW:matrix.org | This Week in Matrix
@@ -145,12 +186,22 @@ public.state_group_edges - 122 MB
145186```
146187
147188## Lookup room state info by list of room_id
189+ You get the same information when you use the
190+ [ admin API] ( ../../admin_api/rooms.md#room-details-api ) .
148191``` sql
149- SELECT rss .room_id , rss .name , rss .canonical_alias , rss .topic , rss .encryption , rsc .joined_members , rsc .local_users_in_room , rss .join_rules
150- FROM room_stats_state rss
151- LEFT JOIN room_stats_current rsc USING (room_id)
152- WHERE room_id IN (WHERE room_id IN (
153- ' !OGEhHVWSdvArJzumhm:matrix.org' ,
154- ' !YTvKGNlinIzlkMTVRl:matrix.org'
155- )
156- ```
192+ SELECT rss .room_id , rss .name , rss .canonical_alias , rss .topic , rss .encryption ,
193+ rsc .joined_members , rsc .local_users_in_room , rss .join_rules
194+ FROM room_stats_state rss
195+ LEFT JOIN room_stats_current rsc USING (room_id)
196+ WHERE room_id IN ( WHERE room_id IN (
197+ ' !OGEhHVWSdvArJzumhm:matrix.org' ,
198+ ' !YTvKGNlinIzlkMTVRl:matrix.org'
199+ );
200+ ```
201+
202+ ## Show users and devices that have not been online for a while
203+ ``` sql
204+ SELECT user_id, device_id, user_agent, TO_TIMESTAMP(last_seen / 1000 ) AS " last_seen"
205+ FROM devices
206+ WHERE last_seen < DATE_PART(' epoch' , NOW() - INTERVAL ' 3 month' ) * 1000 ;
207+ ```
0 commit comments