You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Percona has implemented several changes related to *MySQL*’s fast index creation
4
-
feature. Fast index creation was implemented in *MySQL* as a way to speed up the
5
-
process of adding or dropping indexes on tables with many rows.
3
+
## What fast index creation is
6
4
7
-
This feature implements a session variable that enables extended fast index
8
-
creation. Besides optimizing DDL directly,
9
-
[expand_fast_index_creation](#expanded-fast-index-creation) may also optimize index access for
10
-
subsequent DML statements because using it results in much less fragmented
11
-
indexes.
5
+
In *InnoDB*, secondary indexes are separate B-tree structures from the clustered
6
+
index (the primary key). When the server creates a new secondary index on
7
+
an existing table, it can do so in two conceptually different ways:
12
8
13
-
## The **mysqldump** command
9
+
1. Row-by-row maintenance — For each row, insert that row’s entries into the
10
+
new secondary index as you go. Those inserts arrive in primary-key order, not
11
+
in secondary-key order, so the growing B-tree suffers many random-looking
12
+
page splits and a large amount of write amplification. If the server is
13
+
also copying the table (rebuild `ALTER TABLE`), the same pattern applies:
14
+
every row copied into the new table must update every secondary index
15
+
immediately.
14
16
15
-
A new option, `--innodb-optimize-keys`, was implemented in **mysqldump**. It
16
-
changes the way *InnoDB* tables are dumped, so that secondary and foreign keys
17
+
2. Fast index creation (sorted / bulk build) — The server scans the table’s
18
+
clustered index in primary-key order, generates secondary-key tuples, sorts
19
+
them (often using external merge sort), and builds the secondary index from
20
+
that ordered stream. Work is staged in temporary files under the configured
21
+
`tmpdir`, then merged into a compact B-tree. That path avoids the worst
22
+
random-insert behavior of the row-by-row approach and usually completes with
23
+
less I/O and a less fragmented index.
24
+
25
+
So fast index creation means: build the secondary index from a sorted
26
+
stream after reading the table (or a copy) in clustered index order, instead of
27
+
growing the index by arbitrary-order inserts during the same phase as the data
28
+
copy.
29
+
30
+
Dropping an index is already a cheap metadata change in many cases; the
31
+
performance win is dominated by creating indexes on large tables.
32
+
33
+
## How this differs from Oracle MySQL {{vers}}
34
+
35
+
The figure below contrasts a typical Oracle MySQL workflow with Percona Server
36
+
when expanded fast index creation is in use (including
37
+
`mysqldump --innodb-optimize-keys` during restore).
38
+
39
+

40
+
41
+
The following compares Percona Server for MySQL with Oracle MySQL {{vers}} on
42
+
code paths that still rebuild the table. InnoDB classifies each `ALTER TABLE`
43
+
operation by algorithm (`INSTANT`, `INPLACE`, `COPY`, and so on); those
44
+
classifications can change between releases, so treat the [InnoDB online DDL
With this optimization enabled, the server does not only make index
181
+
maintenance cheaper in memory: it materializes each secondary index in
182
+
temporary files (sorted runs and merge passes) and only then merges the
183
+
result into the final *InnoDB* index. That can consume far more transient
184
+
space than a rough “indexes fit in the tablespace” estimate suggests.
46
185
47
-
*InnoDB* fast index creation uses temporary files in tmpdir for all indexes
48
-
being created. So make sure you have enough tmpdir space when using
49
-
[expand_fast_index_creation](#expanded-fast-index-creation). It is a session variable, so you can
50
-
temporarily switch it off if you are short on tmpdir space and/or don’t want
51
-
this optimization to be used for a specific table.
186
+
Size the filesystem using the secondary index footprint you are
187
+
rebuilding, not the primary table size alone. You typically need
188
+
well above the on-disk size of those secondary indexes as free
189
+
space under `tmpdir`, on top of anything else the same `ALTER TABLE`or
190
+
`OPTIMIZE TABLE` already needs. For example, a table with about 500 GB
191
+
of data and about 200 GB of secondary indexes may still require
192
+
significantly more than 200 GB of free `tmpdir` space while those
193
+
indexes are being built.
194
+
195
+
If `tmpdir` fills during the operation, the statement fails and rolls
196
+
back. You lose the work done up to that pointand must free or enlarge
197
+
storage (orpoint`tmpdir` at a larger volume), or run with
198
+
`expand_fast_index_creation` disabled for that job, before retrying.
199
+
200
+
[`expand_fast_index_creation`](#expanded-fast-index-creation) is a session or
201
+
global variable: you can set it to `OFF` for a single session if `tmpdir` is
202
+
too small for a specific table or maintenance window.
52
203
53
204
There’s also a number of cases when this optimization is not applicable:
54
205
@@ -62,16 +213,16 @@ dropping keys that are part of a FOREIGN KEY constraint;
62
213
*`ALTER TABLE`and`OPTIMIZE TABLE` always process partitioned tables as if
63
214
[expand_fast_index_creation](#expanded-fast-index-creation) is OFF;
64
215
65
-
***mysqldump --innodb-optimize-keys** ignores foreign keys because
216
+
* mysqldump --innodb-optimize-keys ignores foreign keys because
66
217
*InnoDB* requires a full table rebuild onforeign key changes. So adding them
67
218
back with a separate `ALTER TABLE` after restoring the data from a dump
68
219
would actually make the restore slower;
69
220
70
-
***mysqldump --innodb-optimize-keys** ignores indexes on
221
+
* mysqldump --innodb-optimize-keys ignores indexes on
71
222
`AUTO_INCREMENT` columns, because they must be indexed, so it is impossible
72
223
to temporarily drop the corresponding index;
73
224
74
-
***mysqldump --innodb-optimize-keys** ignores the first UNIQUE index on
225
+
* mysqldump --innodb-optimize-keys ignores the first UNIQUE index on
75
226
non-nullable columns when the table has no `PRIMARY KEY` defined, because in
76
227
this case *InnoDB* picks such an index as the clustered one.
77
228
@@ -86,12 +237,24 @@ this case *InnoDB* picks such an index as the clustered one.
86
237
| Scope: | Local/Global |
87
238
| Dynamic: | Yes |
88
239
| Data type | Boolean |
89
-
| Default value | ON/OFF |
240
+
| Default value | OFF |
241
+
242
+
When set to `ON`, *InnoDB* may drop eligible non-unique secondary indexes for the
243
+
data-copy phase of rebuild-style `ALTER TABLE`and`OPTIMIZE TABLE`, then
244
+
recreate them with the sorted bulk build described [above](#what-fast-index-creation-is).
245
+
246
+
## Related documentation
90
247
91
-
!!! admonition "See also"
248
+
### In this manual
92
249
93
-
[Improved InnoDB fast index creation :octicons-link-external-16:](https://www.mysqlperformanceblog.com/2011/11/06/improved-innodb-fast-index-creation/)
250
+
* [Percona Server for MySQL feature comparison](feature-comparison.md) — how this capability compares to MySQL {{vers}}
251
+
* [Percona Server for MySQL variables](percona-server-system-variables.md) — full list of Percona-specific system variables, including `expand_fast_index_creation`
252
+
* [Extended mysqldump](extended-mysqldump.md) — Percona `mysqldump` enhancements, including `--innodb-optimize-keys`
253
+
* [InnoDB page fragmentation counters](innodb-fragmentation-count.md) — monitoring index fragmentation
94
254
95
-
[Thinking about running OPTIMIZE on your InnoDB Table? Stop! :octicons-link-external-16:](https://www.mysqlperformanceblog.com/2010/12/09/thinking-about-running-optimize-on-your-innodb-table-stop/)
255
+
### MySQL Reference Manual
96
256
257
+
* [InnoDB and online DDL :octicons-link-external-16:](https://dev.mysql.com/doc/refman/{{vers}}/en/innodb-online-ddl.html)
0 commit comments