text:
6.3.1 Locking Methods
Currently, MySQL supports table-level locking for ISAM, MyISAM, and MEMORY (HEAP) tables, page-level locking for BDB tables, and row-level locking for InnoDB tables.
In many cases, you can make an educated guess about which locking type is best for an application, but generally it's very hard to say that a given lock type is better than another. Everything depends on the application and different parts of an application may require different lock types.
To decide whether you want to use a storage engine with row-level locking, you will want to look at what your application does and what mix of select and update statements it uses. For example, most Web applications do lots of selects, very few deletes, updates based mainly on key values, and inserts into some specific tables. The base MySQL MyISAM setup is very well tuned for this.
Table locking in MySQL is deadlock-free for storage engines that use table-level locking. Deadlock avoidance is managed by always requesting all needed locks at once at the beginning of a query and always locking the tables in the same order.
The table-locking method MySQL uses for WRITE locks works as follows:
If there are no locks on the table, put a write lock on it.
Otherwise, put the lock request in the write lock queue.
The table-locking method MySQL uses for READ locks works as follows:
If there are no write locks on the table, put a read lock on it.
Otherwise, put the lock request in the read lock queue.
When a lock is released, the lock is made available to the threads in the write lock queue, then to the threads in the read lock queue.
This means that if you have many updates for a table, SELECT statements will wait until there are no more updates.
Starting in MySQL 3.23.33, you can analyze the table lock contention on your system by checking the Table_locks_waited and Table_locks_immediate status variables:
mysql> SHOW STATUS LIKE 'Table%'; +———————–+———+ | Variable_name | Value | +———————–+———+ | Table_locks_immediate | 1151552 | | Table_locks_waited | 15324 | +———————–+———+
As of MySQL 3.23.7 (3.23.25 for Windows), you can freely mix concurrent INSERT and SELECT statements for a MyISAM table without locks if the INSERT statements are non-conflicting. That is, you can insert rows into a MyISAM table at the same time other clients are reading from it. No conflict occurs if the data file contains no free blocks in the middle, because in that case, records always are inserted at the end of the data file. (Holes can result from rows having been deleted from or updated in the middle of the table.) If there are holes, concurrent inserts are re-enabled automatically when all holes have been filled with new data.
If you want to do many INSERT and SELECT operations on a table when concurrent inserts are not possible, you can insert rows in a temporary table and update the real table with the records from the temporary table once in a while. This can be done with the following code:
mysql> LOCK TABLES real_table WRITE, insert_table WRITE; mysql> INSERT INTO real_table SELECT * FROM insert_table; mysql> TRUNCATE TABLE insert_table; mysql> UNLOCK TABLES;
InnoDB uses row locks and BDB uses page locks. For the InnoDB and BDB storage engines, deadlock is possible. This is because InnoDB automatically acquires row locks and BDB acquires page locks during the processing of SQL statements, not at the start of the transaction.
Advantages of row-level locking:
Fewer lock conflicts when accessing different rows in many threads.
Fewer changes for rollbacks.
Makes it possible to lock a single row a long time.
Disadvantages of row-level locking:
Takes more memory than page-level or table-level locks.
Is slower than page-level or table-level locks when used on a large part of the table because you must acquire many more locks.
Is definitely much worse than other locks if you often do GROUP BY operations on a large part of the data or if you often must scan the entire table.
With higher-level locks, you can also more easily support locks of different types to tune the application, because the lock overhead is less than for row-level locks.
Table locks are superior to page-level or row-level locks in the following cases:
Most statements for the table are reads.
- Read and updates on strict keys, where you update or delete a row that can be fetched with a single key read:
UPDATE tbl_name SET column=value WHERE unique_key_col=key_value; DELETE FROM tbl_name WHERE unique_key_col=key_value;
SELECT combined with concurrent INSERT statements, and very few UPDATE and DELETE statements.
Many scans or GROUP BY operations on the entire table without any writers.
Options other than row-level or page-level locking:
Versioning (such as we use in MySQL for concurrent inserts) where you can have one writer at the same time as many readers. This means that the database/table supports different views for the data depending on when you started to access it. Other names for this are time travel, copy on write, or copy on demand.
Copy on demand is in many cases much better than page-level or row-level locking. However, the worst case does use much more memory than when using normal locks.
Instead of using row-level locks, you can use application-level locks, such as GET_LOCK() and RELEASE_LOCK() in MySQL. These are advisory locks, so they work only in well-behaved applications.
6.3.2 Table Locking Issues
To achieve a very high lock speed, MySQL uses table locking (instead of page, row, or column locking) for all storage engines except InnoDB and BDB.
For InnoDB and BDB tables, MySQL only uses table locking if you explicitly lock the table with LOCK TABLES. For these table types, we recommend you to not use LOCK TABLES at all, because InnoDB uses automatic row-level locking and BDB uses page-level locking to ensure transaction isolation.
For large tables, table locking is much better than row locking for most applications, but there are some pitfalls.
Table locking enables many threads to read from a table at the same time, but if a thread wants to write to a table, it must first get exclusive access. During the update, all other threads that want to access this particular table must wait until the update is done.
Table updates normally are considered to be more important than table retrievals, so they are given higher priority. This should ensure that updates to a table are not "starved" even if there is heavy SELECT activity for the table.
Table locking causes problems in cases such as when a thread is waiting because the disk is full and free space needs to become available before the thread can proceed. In this case, all threads that want to access the problem table will also be put in a waiting state until more disk space is made available.
Table locking is also disadvantageous under the following scenario:
A client issues a SELECT that takes a long time to run.
Another client then issues an UPDATE on the same table. This client will wait until the SELECT is finished.
Another client issues another SELECT statement on the same table. Because UPDATE has higher priority than SELECT, this SELECT will wait for the UPDATE to finish. It will also wait for the first SELECT to finish!
The following list describes some ways to avoid or reduce contention caused by table locking:
Try to get the SELECT statements to run faster. You might have to create some summary tables to do this.
Start mysqld with –low-priority-updates. This gives all statements that update (modify) a table lower priority than SELECT statements. In this case, the second SELECT statement in the preceding scenario would execute before the INSERT statement, and would not need to wait for the first SELECT to finish.
You can specify that all updates issued in a specific connection should be done with low priority by using the SET LOW_PRIORITY_UPDATES=1 statement.
You can give a specific INSERT, UPDATE, or DELETE statement lower priority with the LOW_PRIORITY attribute.
You can give a specific SELECT statement higher priority with the HIGH_PRIORITY attribute.
Starting from MySQL 3.23.7, you can start mysqld with a low value for the max_write_lock_count system variable to force MySQL to temporarily elevate the priority of all SELECT statements that are waiting for a table after a specific number of inserts to the table occur. This allows READ locks after a certain number of WRITE locks.
If you have problems with INSERT combined with SELECT, switch to using MyISAM tables, which support concurrent SELECT and INSERT statements.
If you mix inserts and deletes on the same table, INSERT DELAYED may be of great help.
If you have problems with mixed SELECT and DELETE statements, the LIMIT option to DELETE may help.
Using SQL_BUFFER_RESULT with SELECT statements can help to make the duration of table locks shorter.
You could change the locking code in mysys/thr_lock.c to use a single queue. In this case, write locks and read locks would have the same priority, which might help some applications.
Here are some tips about table locking in MySQL:
Concurrent users are not a problem if you don't mix updates with selects that need to examine many rows in the same table.
You can use LOCK TABLES to speed up things (many updates within a single lock is much faster than updates without locks). Splitting table contents into separate tables may also help.
If you encounter speed problems with table locks in MySQL, you may be able to improve performance by converting some of your tables to InnoDB or BDB tables. See Chapter 9, "The InnoDB Storage Engine." See Section 8.4, "The BDB (BerkeleyDB) Storage Engine."
{mospagebreak title=6.4 Optimizing Database Structure}
6.4.1 Design Choices
MySQL keeps row data and index data in separate files. Many (almost all) other databases mix row and index data in the same table. We believe that the MySQL choice is better for a very wide range of modern systems.
Another way to store the row data is to keep the information for each column in a separate area (examples are SDBM and Focus). This will cause a performance hit for every query that accesses more than one column. Because this degenerates so quickly when more than one column is accessed, we believe that this model is not good for general-purpose databases.
The more common case is that the index and data are stored together (as in Oracle/Sybase, et al). In this case, you will find the row information at the leaf page of the index. The good thing with this layout is that it, in many cases, depending on how well the index is cached, saves a disk read. The bad things with this layout are:
Table scanning is much slower because you have to read through the indexes to get at the data.
You can't use only the index table to retrieve data for a query.
You lose a lot of space, because you must duplicate indexes from the nodes (because you can't store the row in the nodes).
Deletes will degenerate the table over time (because indexes in nodes are usually not updated on delete).
It's harder to cache only the index data.
6.4.2 Make Your Data as Small as Possible
One of the most basic optimizations is to design your tables to take as little space on the disk as possible. This can give huge improvements because disk reads are faster, and smaller tables normally require less main memory while their contents are being actively processed during query execution. Indexing also is a lesser resource burden if done on smaller columns.
MySQL supports a lot of different table types and row formats. For each table, you can decide which storage/index method to use. Choosing the right table format for your application may give you a big performance gain. See Chapter 8, "MySQL Storage Engines and Table Types."
You can get better performance on a table and minimize storage space using the techniques listed here:
Use the most efficient (smallest) data types possible. MySQL has many specialized types that save disk space and memory.
Use the smaller integer types if possible to get smaller tables. For example, MEDIUMINT is often better than INT.
Declare columns to be NOT NULL if possible. It makes everything faster and you save one bit per column. If you really need NULL in your application, you should definitely use it. Just avoid having it on all columns by default.
For MyISAM tables, if you don't have any variable-length columns (VARCHAR, TEXT, or BLOB columns), a fixed-size record format is used. This is faster but unfortunately may waste some space. See Section 8.1.3, "MyISAM Table Storage Formats."
The primary index of a table should be as short as possible. This makes identification of each row easy and efficient.
Create only the indexes that you really need. Indexes are good for retrieval but bad when you need to store things fast. If you mostly access a table by searching on a combination of columns, make an index on them. The first index part should be the most used column. If you are always using many columns, you should use the column with more duplicates first to get better compression of the index.
If it's very likely that a column has a unique prefix on the first number of characters, it's better to index only this prefix. MySQL supports an index on the leftmost part of a character column. Shorter indexes are faster not only because they take less disk space, but also because they will give you more hits in the index cache and thus fewer disk seeks. See Section 6.5.2, "Tuning Server Parameters."
In some circumstances, it can be beneficial to split into two a table that is scanned very often. This is especially true if it is a dynamic format table and it is possible to use a smaller static format table that can be used to find the relevant rows when scanning the table.
6.4.3 Column Indexes
All MySQL column types can be indexed. Use of indexes on the relevant columns is the best way to improve the performance of SELECT operations.
The maximum number of indexes per table and the maximum index length is defined per storage engine. See Chapter 8, "MySQL Storage Engines and Table Types." All storage engines support at least 16 indexes per table and a total index length of at least 256 bytes. Most storage engines have higher limits.
With col_name(length) syntax in an index specification, you can create an index that uses only the first length bytes of a CHAR or VARCHAR column. Indexing only a prefix of column values like this can make the index file much smaller.
The MyISAM and (as of MySQL 4.0.14) InnoDB storage engines also support indexing on BLOB and TEXT columns. When indexing a BLOB or TEXT column, you must specify a prefix length for the index. For example:
CREATE TABLE test (blob_col BLOB, INDEX(blob_col(10)));
Prefixes can be up to 255 bytes long (or 1000 bytes for MyISAM and InnoDB tables as of MySQL 4.1.2). Note that prefix limits are measured in bytes, whereas the prefix length in CREATE TABLE statements is interpreted as number of characters. Take this into account when specifying a prefix length for a column that uses a multi-byte character set.
As of MySQL 3.23.23, you can also create FULLTEXT indexes. They are used for full-text searches. Only the MyISAM table type supports FULLTEXT indexes and only for CHAR, VARCHAR, and TEXT columns. Indexing always happens over the entire column and partial (prefix) indexing is not supported.
As of MySQL 4.1.0, you can create indexes on spatial column types. Currently, spatial types are supported only by the MyISAM storage engine. Spatial indexes use R-trees.
The MEMORY (HEAP) storage engine supports hash indexes. As of MySQL 4.1.0, the engine also supports B-tree indexes.
6.4.4 Multiple-Column Indexes
MySQL can create indexes on multiple columns. An index may consist of up to 15 columns. For certain column types, you can index a prefix of the column (see Section 6.4.3, "Column Indexes").
A multiple-column index can be considered a sorted array containing values that are created by concatenating the values of the indexed columns.
MySQL uses multiple-column indexes in such a way that queries are fast when you specify a known quantity for the first column of the index in a WHERE clause, even if you don't specify values for the other columns.
Suppose that a table has the following specification:
CREATE TABLE test ( id INT NOT NULL, last_name CHAR(30) NOT NULL, first_name CHAR(30) NOT NULL, PRIMARY KEY (id), INDEX name (last_name,first_name));
The name index is an index over last_name and first_name. The index can be used for queries that specify values in a known range for last_name, or for both last_name and first_name. Therefore, the name index will be used in the following queries:
SELECT * FROM test WHERE last_name='Widenius'; SELECT * FROM test WHERE last_name='Widenius' AND first_name='Michael'; SELECT * FROM test WHERE last_name='Widenius' AND (first_name='Michael' OR first_name='Monty'); SELECT * FROM test WHERE last_name='Widenius' AND first_name >='M' AND first_name < 'N';
However, the name index will not be used in the following queries:
SELECT * FROM test WHERE first_name='Michael'; SELECT * FROM test WHERE last_name='Widenius' OR first_name='Michael';
The manner in which MySQL uses indexes to improve query performance is discussed further in the next section.
{mospagebreak title=6.4.5 How MySQL Uses Indexes}
Indexes are used to find rows with specific column values fast. Without an index, MySQL has to start with the first record and then read through the whole table to find the relevant rows. The bigger the table, the more this costs. If the table has an index for the columns in question, MySQL can quickly determine the position to seek to in the middle of the data file without having to look at all the data. If a table has 1,000 rows, this is at least 100 times faster than reading sequentially. Note that if you need to access almost all 1,000 rows, it is faster to read sequentially, because that minimizes disk seeks.
Most MySQL indexes (PRIMARY KEY, UNIQUE, INDEX, and FULLTEXT) are stored in B-trees. Exceptions are that indexes on spatial column types use R-trees, and MEMORY (HEAP) tables support hash indexes.
Strings are automatically prefix- and end-space compressed.
In general, indexes are used as described in the following discussion. Characteristics specific to hash indexes (as used in MEMORY tables) are described at the end of this section.
To quickly find the rows that match a WHERE clause.
To eliminate rows from consideration. If there is a choice between multiple indexes, MySQL normally uses the index that finds the smallest number of rows.
To retrieve rows from other tables when performing joins.
- To find the MIN() or MAX() value for a specific indexed column key_col. This is optimized by a preprocessor that checks whether you are using WHERE key_part_# = constant on all key parts that occur before key_col in the index. In this case, MySQL will do a single key lookup for each MIN() or MAX() expression and replace it with a constant. If all expressions are replaced with constants, the query will return at once. For example:
SELECT MIN(key_part2),MAX(key_part2) FROM tbl_name WHERE key_part1=10;
To sort or group a table if the sorting or grouping is done on a leftmost prefix of a usable key (for example, ORDER BY key_part1, key_part2). If all key parts are followed by DESC, the key is read in reverse order. See Section 6.2.9, "How MySQL Optimizes ORDER BY."
- In some cases, a query can be optimized to retrieve values without consulting the data rows. If a query uses only columns from a table that are numeric and that form a leftmost prefix for some key, the selected values may be retrieved from the index tree for greater speed:
SELECT key_part3 FROM tbl_name WHERE key_part1=1
Suppose that you issue the following SELECT statement:
mysql> SELECT * FROM tbl_name WHERE col1=val1 AND col2=val2;
If a multiple-column index exists on col1 and col2, the appropriate rows can be fetched directly. If separate single-column indexes exist on col1 and col2, the optimizer tries to find the most restrictive index by deciding which index will find fewer rows and using that index to fetch the rows.
If the table has a multiple-column index, any leftmost prefix of the index can be used by the optimizer to find rows. For example, if you have a three-column index on (col1, col2, col3), you have indexed search capabilities on (col1), (col1, col2), and (col1, col2, col3).
MySQL can't use a partial index if the columns don't form a leftmost prefix of the index. Suppose that you have the SELECT statements shown here:
SELECT * FROM tbl_name WHERE col1=val1; SELECT * FROM tbl_name WHERE col2=val2; SELECT * FROM tbl_name WHERE col2=val2 AND col3=val3;
If an index exists on (col1, col2, col3), only the first of the preceding queries uses the index. The second and third queries do involve indexed columns, but (col2) and (col2, col3) are not leftmost prefixes of (col1, col2, col3).
An index is used for columns that you compare with the =, >, >=, <, <=, or BETWEEN operators.
MySQL also uses indexes for LIKE comparisons if the argument to LIKE is a constant string that doesn't start with a wildcard character. For example, the following SELECT statements use indexes:
SELECT * FROM tbl_name WHERE key_col LIKE 'Patrick%'; SELECT * FROM tbl_name WHERE key_col LIKE 'Pat%_ck%';
In the first statement, only rows with 'Patrick' <= key_col < 'Patricl' are considered. In the second statement, only rows with 'Pat' <= key_col < 'Pau' are considered.
The following SELECT statements will not use indexes:
SELECT * FROM tbl_name WHERE key_col LIKE '%Patrick%'; SELECT * FROM tbl_name WHERE key_col LIKE other_col;
In the first statement, the LIKE value begins with a wildcard character. In the second statement, the LIKE value is not a constant.
MySQL 4.0 and up performs an additional LIKE optimization. If you use … LIKE '%string%' and string is longer than three characters, MySQL will use the Turbo Boyer-Moore algorithm to initialize the pattern for the string and then use this pattern to perform the search quicker.
Searching using col_name IS NULL will use indexes if col_name is indexed.
Any index that doesn't span all AND levels in the WHERE clause is not used to optimize the query. In other words, to be able to use an index, a prefix of the index must be used in every AND group.
The following WHERE clauses use indexes:
… WHERE index_part1=1 AND index_part2=2 AND other_column=3 /* index = 1 OR index = 2 */ … WHERE index=1 OR A=10 AND index=2 /* optimized like "index_part1='hello'" */ … WHERE index_part1='hello' AND index_part3=5 /* Can use index on index1 but not on index2 or index3 */ … WHERE index1=1 AND index2=2 OR index1=3 AND index3=3;
These WHERE clauses do not use indexes:
/* index_part1 is not used */ … WHERE index_part2=1 AND index_part3=2 /* Index is not used in both AND parts */ … WHERE index=1 OR A=10 /* No index spans all rows */ … WHERE index_part1=1 OR index_part2=10
Sometimes MySQL will not use an index, even if one is available. One way this occurs is when the optimizer estimates that using the index would require MySQL to access a large percentage of the rows in the table. (In this case, a table scan is probably much faster, because it will require many fewer seeks.) However, if such a query uses LIMIT to only retrieve part of the rows, MySQL will use an index anyway, because it can much more quickly find the few rows to return in the result.
Hash indexes have somewhat different characteristics than those just discussed:
They are used only for = or <=> comparisons (but are very fast).
The optimizer cannot use a hash index to speed up ORDER BY operations. (This type of index cannot be used to search for the next entry in order.)
MySQL cannot determine approximately how many rows there are between two values (this is used by the range optimizer to decide which index to use). This may affect some queries if you change a MyISAM table to a hash-indexed MEMORY table.
Only whole keys can be used to search for a row. (With a B-tree index, any prefix of the key can be used to find rows.)
6.4.6 The MyISAM Key Cache
To minimize disk I/O, the MyISAM storage engine employs a strategy that is used by many database management systems. It exploits a cache mechanism to keep the most frequently accessed table blocks in memory:
For index blocks, a special structure called the key cache (key buffer) is maintained. The structure contains a number of block buffers where the most-used index blocks are placed.
For data blocks, MySQL uses no special cache. Instead it relies on the native operating system filesystem cache.
This section first describes the basic operation of the MyISAM key cache. Then it discusses changes made in MySQL 4.1 that improve key cache performance and that enable you to better control cache operation:
Access to the key cache no longer is serialized among threads. Multiple threads can access the cache concurrently.
You can set up multiple key caches and assign table indexes to specific caches.
The key cache mechanism also is used for ISAM tables. However, the significance of this fact is on the wane. ISAM table use has been decreasing since MySQL 3.23 when MyISAM was introduced. MySQL 4.1 carries this trend further; the ISAM storage engine is disabled by default.
You can control the size of the key cache by means of the key_buffer_size system variable. If this variable is set equal to zero, no key cache is used. The key cache also is not used if the key_buffer_size value is too small to allocate the minimal number of block buffers (8).
When the key cache is not operational, index files are accessed using only the native filesystem buffering provided by the operating system. (In other words, table index blocks are accessed using the same strategy as that employed for table data blocks.)
An index block is a contiguous unit of access to the MyISAM index files. Usually the size of an index block is equal to the size of nodes of the index B-tree. (Indexes are represented on disk using a B-tree data structure. Nodes at the bottom of the tree are leaf nodes. Nodes above the leaf nodes are non-leaf nodes.)
All block buffers in a key cache structure are the same size. This size can be equal to, greater than, or less than the size of a table index block. Usually one of these two values is a multiple of the other.
When data from any table index block must be accessed, the server first checks whether it is available in some block buffer of the key cache. If it is, the server accesses data in the key cache rather than on disk. That is, it reads from the cache or writes into it rather than reading from or writing to disk. Otherwise, the server chooses a cache block buffer containing a different table index block (or blocks) and replaces the data there by a copy of required table index block. As soon as the new index block is in the cache, the index data can be accessed.
If it happens that a block selected for replacement has been modified, the block is considered "dirty." In this case, before being replaced, its contents are flushed to the table index from which it came.
Usually the server follows an LRU (Least Recently Used) strategy: When choosing a block for replacement, it selects the least recently used index block. To be able to make such a choice easy, the key cache module maintains a special queue (LRU chain) of all used blocks. When a block is accessed, it is placed at the end of the queue. When blocks need to be replaced, blocks at the beginning of the queue are the least recently used and become the first candidates for eviction.
{mospagebreak title=126.96.36.199 Shared Key Cache Access}
Prior to MySQL 4.1, access to the key cache is serialized: No two threads can access key cache buffers simultaneously. The server processes a request for an index block only after it has finished processing the previous request. As a result, a request for an index block not present in any key cache buffer blocks access by other threads while a buffer is being updated to contain the requested index block.
Starting from version 4.1.0, the server supports shared access to the key cache:
A buffer that is not being updated can be accessed by multiple threads.
A buffer that is being updated causes threads that need to use it to wait until the update is complete.
Multiple threads can initiate requests that result in cache block replacements, as long as they do not interfere with each other (that is, as long as they need different index blocks, and thus cause different cache blocks to be replaced).
Shared access to the key cache allows the server to improve throughput significantly.
184.108.40.206 Multiple Key Caches
Shared access to the key cache improves performance but does not eliminate contention among threads entirely. They still compete for control structures that manage access to the key cache buffers. To reduce key cache access contention further, MySQL 4.1.1 offers the feature of multiple key caches. This allows you to assign different table indexes to different key caches.
When there can be multiple key caches, the server must know which cache to use when processing queries for a given MyISAM table. By default, all MyISAM table indexes are cached in the default key cache. To assign table indexes to a specific key cache, use the CACHE INDEX statement.
For example, the following statement assigns indexes from the tables t1, t2, and t3 to the key cache named hot_cache:
mysql> CACHE INDEX t1, t2, t3 IN hot_cache; +———+——————–+———-+———-+ | Table | Op | Msg_type | Msg_text | +———+——————–+———-+———-+ | test.t1 | assign_to_keycache | status | OK | | test.t2 | assign_to_keycache | status | OK | | test.t3 | assign_to_keycache | status | OK | +———+——————–+———-+———-+
Note: If the server has been built with the ISAM storage engine enabled, ISAM tables use the key cache mechanism. However, ISAM indexes use only the default key cache and cannot be reassigned to a different cache.
The key cache referred to in a CACHE INDEX statement can be created by setting its size with a SET GLOBAL parameter setting statement or by using server startup options. For example:
mysql> SET GLOBAL keycache1.key_buffer_size=128*1024;
To destroy a key cache, set its size to zero:
mysql> SET GLOBAL keycache1.key_buffer_size=0;
Key cache variables are structured system variables that have a name and components. For keycache1.key_buffer_size, keycache1 is the cache variable name and key_buffer_size is the cache component.
By default, table indexes are assigned to the main (default) key cache created at the server startup. When a key cache is destroyed, all indexes assigned to it are reassigned to the default key cache.
For a busy server, we recommend a strategy that uses three key caches:
A hot key cache that takes up 20% of the space allocated for all key caches. This is used for tables that are heavily used for searches but that are not updated.
A cold key cache that takes up 20% of the space allocated for all key caches. This is used for medium-sized intensively modified tables, such as temporary tables.
A warm key cache that takes up 60% of the key cache space. This is the default key cache, to be used by default for all other tables.
One reason the use of three key caches is beneficial is that access to one key cache structure does not block access to the others. Queries that access tables assigned to one cache do not compete with queries that access tables assigned to another cache. Performance gains occur for other reasons as well:
The hot cache is used only for retrieval queries, so its contents are never modified. Consequently, whenever an index block needs to be pulled in from disk, the contents of the cache block chosen for replacement need not be flushed first.
For an index assigned to the hot cache, if there are no queries requiring an index scan, there is a high probability that the index blocks corresponding to non-leaf nodes of the index B-tree will remain in the cache.
An update operation most frequently executed for temporary tables is performed much faster when the updated node already is in the cache and need not be read in from disk first. If the size of the indexes of the temporary tables are comparable with the size of cold key cache, the probability is very high that the updated node already will be in the cache.
220.127.116.11 Midpoint Insertion Strategy
By default, the key cache management system of MySQL 4.1 uses the LRU strategy for choosing key cache blocks to be evicted, but it also supports a more sophisticated method called the "midpoint insertion strategy."
When using the midpoint insertion strategy, the LRU chain is divided into two parts: a hot sub-chain and a warm sub-chain. The division point between two parts is not fixed, but the key cache management system takes care that the warm part is not "too short," always containing at least key_cache_division_limit percent of the key cache blocks. key_cache_ division_limit is a component of structured key cache variables, so its value is a parameter that can be set per cache.
When an index block is read from a table into the key cache, it is placed at the end of the warm sub-chain. After a certain number of hits (accesses of the block), it is promoted to the hot sub-chain. At present, the number of hits required to promote a block (3) is the same for all index blocks. In the future, we will allow the hit count to depend on the B-tree level of the node corresponding to an index block: Fewer hits will be required for promotion of an index block if it contains a non-leaf node from the upper levels of the index B-tree than if it contains a leaf node.
A block promoted into the hot sub-chain is placed at the end of the chain. The block then circulates within this sub-chain. If the block stays at the beginning of the sub-chain for a long enough time, it is demoted to the warm chain. This time is determined by the value of the key_cache_age_threshold component of the key cache.
The threshold value prescribes that, for a key cache containing N blocks, the block at the beginning of the hot sub-chain not accessed within the last N*key_cache_age_threshold/100 hits is to be moved to the beginning of the warm sub-chain. It then becomes the first candidate for eviction, because blocks for replacement always are taken from the beginning of the warm sub-chain.
The midpoint insertion strategy allows you to keep more-valued blocks always in the cache. If you prefer to use the plain LRU strategy, leave the key_cache_division_limit value set to its default of 100.
The midpoint insertion strategy helps to improve performance when execution of a query that requires an index scan effectively pushes out of the cache all the index blocks corresponding to valuable high-level B-tree nodes. To avoid this, you must use a midpoint insertion strategy with the key_cache_division_limit set to much less than 100. Then valuable frequently hit nodes will be preserved in the hot sub-chain during an index scan operation as well.
220.127.116.11 Index Preloading
If there are enough blocks in a key cache to hold blocks of an entire index, or at least the blocks corresponding to its non-leaf nodes, then it makes sense to preload the key cache with index blocks before starting to use it. Preloading allows you to put the table index blocks into a key cache buffer in the most efficient way: by reading the index blocks from disk sequentially.
Without preloading, the blocks still will be placed into the key cache as needed by queries. Although the blocks will stay in the cache, because there are enough buffers for all of them, they will be fetched from disk in a random order, not sequentially.
To preload an index into a cache, use the LOAD INDEX INTO CACHE statement. For example, the following statement preloads nodes (index blocks) of indexes of the tables t1 and t2:
mysql> LOAD INDEX INTO CACHE t1, t2 IGNORE LEAVES; +———+————–+———-+———-+ | Table | Op | Msg_type | Msg_text | +———+————–+———-+———-+ | test.t1 | preload_keys | status | OK | | test.t2 | preload_keys | status | OK | +———+————–+———-+———-+
The IGNORE LEAVES modifier causes only blocks for the non-leaf nodes of the index to be preloaded. Thus, the statement shown preloads all index blocks from t1, but only blocks for the non-leaf nodes from t2.
If an index has been assigned to a key cache using a CACHE INDEX statement, preloading places index blocks into that cache. Otherwise, the index is loaded into the default key cache.
220.127.116.11 Key Cache Block Size
MySQL 4.1 introduces a new key_cache_block_size variable on a per-key cache basis. This variable specifies the size of the block buffers for a key cache. It is intended to allow tuning of the performance of I/O operations for index files.
The best performance for I/O operations is achieved when the size of read buffers is equal to the size of the native operating system I/O buffers. But setting the size of key nodes equal to the size of the I/O buffer does not always ensure the best overall performance. When reading the big leaf nodes, the server pulls in a lot of unnecessary data, effectively preventing reading other leaf nodes.
Currently, you cannot control the size of the index blocks in a table. This size is set by the server when the .MYI index file is created, depending on the size of the keys in the indexes present in the table definition. In most cases, it is set equal to the I/O buffer size. In the future, this will be changed and then key_cache_block_size variable will be fully employed.
{mospagebreak title=220.127.116.11 Restructuring a Key Cache}
A key cache can be restructured at any time by updating its parameter values. For example:
mysql> SET GLOBAL cold_cache.key_buffer_size=4*1024*1024;
If you assign to either the key_buffer_size or key_cache_block_size key cache component a value that differs from the component's current value, the server destroys the cache's old structure and creates a new one based on the new values. If the cache contains any dirty blocks, the server saves them to disk before destroying and re-creating the cache. Restructuring does not occur if you set other key cache parameters.
When restructuring a key cache, the server first flushes the contents of any dirty buffers to disk. After that, the cache contents become unavailable. However, restructuring does not block queries that need to use indexes assigned to the cache. Instead, the server directly accesses the table indexes using native filesystem caching. Filesystem caching is not as efficient as using a key cache, so although queries will execute, a slowdown can be anticipated. Once the cache has been restructured, it becomes available again for caching indexes assigned to it, and the use of filesystem caching for the indexes ceases.
6.4.7 How MySQL Counts Open Tables
When you execute a mysqladmin status command, you'll see something like this:
Uptime: 426 Running threads: 1 Questions: 11082 Reloads: 1 Open tables: 12
The Open tables value of 12 can be somewhat puzzling if you have only six tables.
MySQL is multi-threaded, so there may be many clients issuing queries for a given table simultaneously. To minimize the problem with multiple client threads having different states on the same file, the table is opened independently by each concurrent thread. This takes some memory but normally increases performance. With MyISAM tables, one extra file descriptor is required for the data file for each client that has the table open. (By contrast, the index file descriptor is shared between all threads.) The ISAM storage engine shares this behavior.
You can read more about this topic in the next section. See Section 6.4.8, "How MySQL Opens and Closes Tables."
6.4.8 How MySQL Opens and Closes Tables
The table_cache, max_connections, and max_tmp_tables system variables affect the maximum number of files the server keeps open. If you increase one or more of these values, you may run up against a limit imposed by your operating system on the per-process number of open file descriptors. Many operating systems allow you to increase the open-files limit, although the method varies widely from system to system. Consult your operating system documentation to determine whether it is possible to increase the limit and how to do so.
table_cache is related to max_connections. For example, for 200 concurrent running connections, you should have a table cache size of at least 200 * N, where N is the maximum number of tables in a join. You also need to reserve some extra file descriptors for temporary tables and files.
Make sure that your operating system can handle the number of open file descriptors implied by the table_cache setting. If table_cache is set too high, MySQL may run out of file descriptors and refuse connections, fail to perform queries, and be very unreliable. You also have to take into account that the MyISAM storage engine needs two file descriptors for each unique open table. You can increase the number of file descriptors available for MySQL with the –open-files-limit startup option to mysqld_safe. See Section A.2.17, "File Not Found."
The cache of open tables will be kept at a level of table_cache entries. The default value is 64; this can be changed with the –table_cache option to mysqld. Note that MySQL may temporarily open even more tables to be able to execute queries.
An unused table is closed and removed from the table cache under the following circumstances:
When the cache is full and a thread tries to open a table that is not in the cache.
When the cache contains more than table_cache entries and a thread is no longer using a table.
When a table flushing operation occurs. This happens when someone issues a FLUSH TABLES statement or executes a mysqladmin flush-tables or mysqladmin refresh command.
When the table cache fills up, the server uses the following procedure to locate a cache entry to use:
Tables that are not currently in use are released, in least recently used order.
If a new table needs to be opened, but the cache is full and no tables can be released, the cache is temporarily extended as necessary.
When the cache is in a temporarily extended state and a table goes from a used to unused state, the table is closed and released from the cache.
A table is opened for each concurrent access. This means the table needs to be opened twice if two threads access the same table or if a thread accesses the table twice in the same query (for example, by joining the table to itself). Each concurrent open requires an entry in the table cache. The first open of any table takes two file descriptors: one for the data file and one for the index file. Each additional use of the table takes only one file descriptor, for the data file. The index file descriptor is shared among all threads.
If you are opening a table with the HANDLER tbl_name OPEN statement, a dedicated table object is allocated for the thread. This table object is not shared by other threads and is not closed until the thread calls HANDLER tbl_name CLOSE or the thread terminates. When this happens, the table is put back in the table cache (if the cache isn't full).
You can determine whether your table cache is too small by checking the mysqld status variable Opened_tables:
mysql> SHOW STATUS LIKE 'Opened_tables'; +—————+——-+ | Variable_name | Value | +—————+——-+ | Opened_tables | 2741 | +—————+——-+
If the value is quite big, even when you haven't issued a lot of FLUSH TABLES statements, you should increase your table cache size. See Section 4.2.3, "Server System Variables," and Section 4.2.4, "Server Status Variables."
6.4.9 Drawbacks to Creating Many Tables in the Same Database
If you have many MyISAM or ISAM tables in a database directory, open, close, and create operations will be slow. If you execute SELECT statements on many different tables, there will be a little overhead when the table cache is full, because for every table that has to be opened, another must be closed. You can reduce this overhead by making the table cache larger.
6.5 Optimizing the MySQL Server
6.5.1 System Factors and Startup Parameter Tuning
We start with system-level factors, because some of these decisions must be made very early to achieve large performance gains. In other cases, a quick look at this section may suffice. However, it is always nice to have a sense of how much can be gained by changing things at this level.
The default operating system to use is very important! To get the best use of multiple-CPU machines, you should use Solaris (because its threads implementation works really well) or Linux (because the 2.2 kernel has really good SMP support). Note that older Linux kernels have a 2GB filesize limit by default. If you have such a kernel and a desperate need for files larger than 2GB, you should get the Large File Support (LFS) patch for the ext2 filesystem. Other filesystems such as ReiserFS and XFS do not have this 2GB limitation.
Before using MySQL in production, we advise you to test it on your intended platform.
Other tips:
If you have enough RAM, you could remove all swap devices. Some operating systems will use a swap device in some contexts even if you have free memory.
Use the –skip-external-locking MySQL option to avoid external locking. This option is on by default as of MySQL 4.0. Before that, it is on by default when compiling with MIT-pthreads, because flock() isn't fully supported by MIT-pthreads on all platforms. It's also on by default for Linux because Linux file locking is not yet safe.
Note that the –skip-external-locking option will not affect MySQL's functionality as long as you run only one server. Just remember to take down the server (or lock and flush the relevant tables) before you run myisamchk. On some systems this option is mandatory, because the external locking does not work in any case.
The only case when you can't use –skip-external-locking is if you run multiple MySQL servers (not clients) on the same data, or if you run myisamchk to check (not repair) a table without telling the server to flush and lock the tables first.
You can still use LOCK TABLES/UNLOCK TABLES even if you are using –skip-external-locking.
{mospagebreak title=6.5.2 Tuning Server Parameters}
You can determine the default buffer sizes used by the mysqld server with this command (prior to MySQL 4.1, omit –verbose):
shell> mysqld –verbose –help
This command produces a list of all mysqld options and configurable system variables. The output includes the default variable values and looks something like this:
back_log current value: 5 bdb_cache_size current value: 1048540 binlog_cache_size current value: 32768 connect_timeout current value: 5 delayed_insert_limit current value: 100 delayed_insert_timeout current value: 300 delayed_queue_size current value: 1000 flush_time current value: 0 interactive_timeout current value: 28800 join_buffer_size current value: 131072 key_buffer_size current value: 1048540 long_query_time current value: 10 lower_case_table_names current value: 0 max_allowed_packet current value: 1048576 max_binlog_cache_size current value: 4294967295 max_connect_errors current value: 10 max_connections current value: 100 max_delayed_threads current value: 20 max_heap_table_size current value: 16777216 max_join_size current value: 4294967295 max_sort_length current value: 1024 max_tmp_tables current value: 32 max_write_lock_count current value: 4294967295 myisam_sort_buffer_size current value: 8388608 net_buffer_length current value: 16384 net_read_timeout current value: 30 net_retry_count current value: 10 net_write_timeout current value: 60 read_buffer_size current value: 131072 read_rnd_buffer_size current value: 262144 slow_launch_time current value: 2 sort_buffer current value: 2097116 table_cache current value: 64 thread_concurrency current value: 10 thread_stack current value: 131072 tmp_table_size current value: 1048576 wait_timeout current value: 28800
If there is a mysqld server currently running, you can see what values it actually is using for the system variables by connecting to it and issuing this statement:
mysql> SHOW VARIABLES;
You can also see some statistical and status indicators for a running server by issuing this statement:
mysql> SHOW STATUS;
System variable and status information also can be obtained using mysqladmin:
shell> mysqladmin variables shell> mysqladmin extended-status
You can find a full description for all system and status variables in Section 4.2.3, "Server System Variables," and Section 4.2.4, "Server Status Variables."
MySQL uses algorithms that are very scalable, so you can usually run with very little memory. However, normally you will get better performance by giving MySQL more memory.
When tuning a MySQL server, the two most important variables to configure are key_buffer_size and table_cache. You should first feel confident that you have these set appropriately before trying to change any other variables.
The following examples indicate some typical variable values for different runtime configurations. The examples use the mysqld_safe script and use —var_name=value syntax to set the variable var_name to the value value. This syntax is available as of MySQL 4.0. For older versions of MySQL, take the following differences into account:
Use safe_mysqld rather than mysqld_safe.
Set variables using –set-variable=var_name=value or -O var_name=value syntax.
For variable names that end in _size, you may need to specify them without _size. For example, the old name for sort_buffer_size is sort_buffer. The old name for read_buffer_size is record_buffer. To see which variables your version of the server recognizes, use mysqld –help.
If you have at least 256MB of memory and many tables and want maximum performance with a moderate number of clients, you should use something like this:
shell> mysqld_safe –key_buffer_size=64M –table_cache=256 –sort_buffer_size=4M –read_buffer_size=1M &
If you have only 128MB of memory and only a few tables, but you still do a lot of sorting, you can use something like this:
shell> mysqld_safe –key_buffer_size=16M –sort_buffer_size=1M
If there are very many simultaneous connections, swapping problems may occur unless mysqld has been configured to use very little memory for each connection. mysqld performs better if you have enough memory for all connections.
With little memory and lots of connections, use something like this:
shell> mysqld_safe –key_buffer_size=512K –sort_buffer_size=100K –read_buffer_size=100K &
Or even this:
shell> mysqld_safe –key_buffer_size=512K –sort_buffer_size=16K –table_cache=32 –read_buffer_size=8K –net_buffer_length=1K &
If you are doing GROUP BY or ORDER BY operations on tables that are much larger than your available memory, you should increase the value of read_rnd_buffer_size to speed up the reading of rows after sorting operations.
When you have installed MySQL, the support-files directory will contain some different my.cnf sample files: my-huge.cnf, my-large.cnf, my-medium.cnf, and my-small.cnf. You can use these as a basis for optimizing your system.
Note that if you specify an option on the command line for mysqld or mysqld_safe, it remains in effect only for that invocation of the server. To use the option every time the server runs, put it in an option file.
To see the effects of a parameter change, do something like this (prior to MySQL 4.1, omit –verbose):
shell> mysqld –key_buffer_size=32M –verbose –help
The variable values are listed near the end of the output. Make sure that the –verbose and –help options are last. Otherwise, the effect of any options listed after them on the command line will not be reflected in the output.
For information on tuning the InnoDB storage engine, see Section 9.12, "InnoDB Performance Tuning Tips."
6.5.3 How Compiling and Linking Affects the Speed of MySQL
Most of the following tests were performed on Linux with the MySQL benchmarks, but they should give some indication for other operating systems and workloads.
You get the fastest executables when you link with -static.
On Linux, you will get the fastest code when compiling with pgcc and -O3. You need about 200MB memory to compile sql_yacc.cc with these options, because gcc/pgcc needs a lot of memory to make all functions inline. You should also set CXX=gcc when configuring MySQL to avoid inclusion of the libstdc++ library, which is not needed. Note that with some versions of pgcc, the resulting code will run only on true Pentium processors, even if you use the compiler option indicating that you want the resulting code to work on all x586-type processors (such as AMD).
By just using a better compiler and better compiler options, you can get a 10-30% speed increase in your application. This is particularly important if you compile the MySQL server yourself.
We have tested both the Cygnus CodeFusion and Fujitsu compilers, but when we tested them, neither was sufficiently bug-free to allow MySQL to be compiled with optimizations enabled.
The standard MySQL binary distributions are compiled with support for all character sets. When you compile MySQL yourself, you should include support only for the character sets that you are going to use. This is controlled by the –with-charset option to configure.
Here is a list of some measurements that we have made:
If you use pgcc and compile everything with -O6, the mysqld server is 1% faster than with gcc 2.95.2.
If you link dynamically (without -static), the result is 13% slower on Linux. Note that you still can use a dynamically linked MySQL library for your client applications. It is the server that is most critical for performance.
If you strip your mysqld binary with strip mysqld, the resulting binary can be up to 4% faster.
For a connection from a client to a server running on the same host, if you connect using TCP/IP rather than a Unix socket file, performance is 7.5% slower. (On Unix, if you connect to the hostname localhost, MySQL uses a socket file by default.)
For TCP/IP connections from a client to a server, connecting to a remote server on another host will be 8-11% slower than connecting to the local server on the same host, even for connections over 100Mb/s Ethernet.
When running our benchmark tests using secure connections (all data encrypted with internal SSL support) performance was 55% slower than for unencrypted connections.
If you compile with –with-debug=full, most queries will be 20% slower. Some queries may take substantially longer; for example, the MySQL benchmarks ran 35% slower. If you use –with-debug (without =full), the slowdown will be only 15%. For a version of mysqld that has been compiled with –with-debug=full, you can disable memory checking at runtime by starting it with the –skip-safemalloc option. The end result in this case should be close to that obtained when configuring with –with-debug.
On a Sun UltraSPARC-IIe, a server compiled with Forte 5.0 is 4% faster than one compiled with gcc 3.2.
On a Sun UltraSPARC-IIe, a server compiled with Forte 5.0 is 4% faster in 32-bit mode than in 64-bit mode.
Compiling with gcc 2.95.2 for UltraSPARC with the -mcpu=v8 -Wa,-xarch=v8plusa options gives 4% more performance.
On Solaris 2.5.1, MIT-pthreads is 8-12% slower than Solaris native threads on a single processor. With more load or CPUs, the difference should be larger.
Compiling on Linux-x86 using gcc without frame pointers (-fomit-frame-pointer or -fomit-frame-pointer -ffixed-ebp) makes mysqld 1-4% faster.
Binary MySQL distributions for Linux that are provided by MySQL AB used to be compiled with pgcc. We had to go back to regular gcc due to a bug in pgcc that would generate code that does not run on AMD. We will continue using gcc until that bug is resolved. In the meantime, if you have a non-AMD machine, you can get a faster binary by compiling with pgcc. The standard MySQL Linux binary is linked statically to make it faster and more portable.
{mospagebreak title=6.5.4 How MySQL Uses Memory}
The following list indicates some of the ways that the mysqld server uses memory. Where applicable, the name of the system variable relevant to the memory use is given:
The key buffer (variable key_buffer_size) is shared by all threads; other buffers used by the server are allocated as needed. See Section 6.5.2, "Tuning Server Parameters."
Each connection uses some thread-specific space:
A stack (default 64KB, variable thread_stack)
A connection buffer (variable net_buffer_length)
A result buffer (variable net_buffer_length)
The connection buffer and result buffer are dynamically enlarged up to max_allowed_packet when needed. While a query is running, a copy of the current query string is also allocated.
All threads share the same base memory.
Only compressed ISAM and MyISAM tables are memory mapped. This is because the 32-bit memory space of 4GB is not large enough for most big tables. When systems with a 64-bit address space become more common, we may add general support for memory mapping.
Each request that performs a sequential scan of a table allocates a read buffer (variable read_buffer_size).
When reading rows in "random" order (for example, after a sort), a random-read buffer may be allocated to avoid disk seeks. (variable read_rnd_buffer_size).
All joins are done in one pass, and most joins can be done without even using a temporary table. Most temporary tables are memory-based (HEAP) tables. Temporary tables with a large record length (calculated as the sum of all column lengths) or that contain BLOB columns are stored on disk.
One problem before MySQL 3.23.2 is that if an internal in-memory heap table exceeds the size of tmp_table_size, the error The table tbl_name is full occurs. From 3.23.2 on, this is handled automatically by changing the in-memory heap table to a disk-based MyISAM table as necessary. To work around this problem for older servers, you can increase the temporary table size by setting the tmp_table_size option to mysqld, or by setting the SQL option SQL_BIG_TABLES in the client program.
In MySQL 3.20, the maximum size of the temporary table is record_buffer*16; if you are using this version, you have to increase the value of record_buffer. You can also start mysqld with the –big-tables option to always store temporary tables on disk. However, this will affect the speed of many complicated queries.
Most requests that perform a sort allocate a sort buffer and zero to two temporary files depending on the result set size. See Section A.4.4, "Where MySQL Stores Temporary Files."
Almost all parsing and calculating is done in a local memory store. No memory overhead is needed for small items, so the normal slow memory allocation and freeing is avoided. Memory is allocated only for unexpectedly large strings; this is done with malloc() and free().
For each MyISAM and ISAM table that is opened, the index file is opened once and the data file is opened once for each concurrently running thread. For each concurrent thread, a table structure, column structures for each column, and a buffer of size 3 * N are allocated (where N is the maximum row length, not counting BLOB columns). A BLOB column requires five to eight bytes plus the length of the BLOB data. The MyISAM and ISAM storage engines maintain one extra row buffer for internal use.
For each table having BLOB columns, a buffer is enlarged dynamically to read in larger BLOB values. If you scan a table, a buffer as large as the largest BLOB value is allocated.
Handler structures for all in-use tables are saved in a cache and managed as a FIFO. By default, the cache has 64 entries. If a table has been used by two running threads at the same time, the cache contains two entries for the table. See Section 6.4.8, "How MySQL Opens and Closes Tables."
A FLUSH TABLES statement or mysqladmin flush-tables command closes all tables that are not in use and marks all in-use tables to be closed when the currently executing thread finishes. This effectively frees most in-use memory.
ps and other system status programs may report that mysqld uses a lot of memory. This may be caused by thread stacks on different memory addresses. For example, the Solaris version of ps counts the unused memory between stacks as used memory. You can verify this by checking available swap with swap -s. We have tested mysqld with several memory-leakage detectors (both commercial and open source), so there should be no memory leaks.
6.5.5 How MySQL Uses DNS
When a new client connects to mysqld, mysqld spawns a new thread to handle the request. This thread first checks whether the hostname is in the hostname cache. If not, the thread attempts to resolve the hostname:
If the operating system supports the thread-safe gethostbyaddr_r() and gethostbyname_r() calls, the thread uses them to perform hostname resolution.
If the operating system doesn't support the thread-safe calls, the thread locks a mutex and calls gethostbyaddr() and gethostbyname() instead. In this case, no other thread can resolve hostnames that are not in the hostname cache until the first thread unlocks the mutex.
You can disable DNS hostname lookups by starting mysqld with the –skip-name-resolve option. However, in this case, you can use only IP numbers in the MySQL grant tables.
If you have a very slow DNS and many hosts, you can get more performance by either disabling DNS lookups with –skip-name-resolve or by increasing the HOST_CACHE_SIZE define (default value: 128) and recompiling mysqld.
You can disable the hostname cache by starting the server with the –skip-host-cache option. To clear the hostname cache, issue a FLUSH HOSTS statement or execute the mysqladmin flush-hosts command.
If you want to disallow TCP/IP connections entirely, start mysqld with the –skip-networking option.
6.6 Disk Issues
Disk seeks are a big performance bottleneck. This problem becomes more apparent when the amount of data starts to grow so large that effective caching becomes impossible. For large databases where you access data more or less randomly, you can be sure that you will need at least one disk seek to read and a couple of disk seeks to write things. To minimize this problem, use disks with low seek times.
Increase the number of available disk spindles (and thereby reduce the seek overhead) by either symlinking files to different disks or striping the disks:
Using symbolic links
This means that, for MyISAM tables, you symlink the index file and/or data file from their usual location in the data directory to another disk (that may also be striped). This makes both the seek and read times better, assuming that the disk is not used for other purposes as well. See Section 6.6.1, "Using Symbolic Links."
Striping means that you have many disks and put the first block on the first disk, the second block on the second disk, and the Nth block on the (N mod number_of_disks) disk, and so on. This means if your normal data size is less than the stripe size (or perfectly aligned), you will get much better performance. Striping is very dependent on the operating system and the stripe size, so benchmark your application with different stripe sizes. See Section 6.1.5, "Using Your Own Benchmarks."
The speed difference for striping is very dependent on the parameters. Depending on how you set the striping parameters and number of disks, you may get differences measured in orders of magnitude. You have to choose to optimize for random or sequential access.
For reliability you may want to use RAID 0+1 (striping plus mirroring), but in this case, you will need 2*N drives to hold N drives of data. This is probably the best option if you have the money for it! However, you may also have to invest in some volume-management software to handle it efficiently.
A good option is to vary the RAID level according to how critical a type of data is. For example, store semi-important data that can be regenerated on a RAID 0 disk, but store really important data such as host information and logs on a RAID 0+1 or RAID N disk. RAID N can be a problem if you have many writes, due to the time required to update the parity bits.
- On Linux, you can get much more performance by using hdparm to configure your disk's interface. (Up to 100% under load is not uncommon.) The following hdparm options should be quite good for MySQL, and probably for many other applications:
hdparm -m 16 -d 1
Note that performance and reliability when using this command depends on your hardware, so we strongly suggest that you test your system thoroughly after using hdparm. Please consult the hdparm man page for more information. If hdparm is not used wisely, filesystem corruption may result, so back up everything before experimenting!
You can also set the parameters for the filesystem that the database uses:
If you don't need to know when files were last accessed (which is not really useful on a database server), you can mount your filesystems with the -o noatime option. That skips updates to the last access time in inodes on the filesystem, which avoids some disk seeks.
On many operating systems, you can set a filesystem to be updated asynchronously by mounting it with the -o async option. If your computer is reasonably stable, this should give you more performance without sacrificing too much reliability. (This flag is on by default on Linux.)
6.6.1 Using Symbolic Links
You can move tables and databases from the database directory to other locations and replace them with symbolic links to the new locations. You might want to do this, for example, to move a database to a file system with more free space or increase the speed of your system by spreading your tables to a different disk.
The recommended way to do this is to just symlink databases to a different disk. Symlink tables only as a last resort.
{mospagebreak title=188.8.131.52 Using Symbolic Links for Databases on Unix}
On Unix, the way to symlink a database is to first create a directory on some disk where you have free space and then create a symlink to it from the MySQL data directory.
shell> mkdir /dr1/databases/test shell> ln -s /dr1/databases/test /path/to/datadir
MySQL doesn't support linking one directory to multiple databases. Replacing a database directory with a symbolic link will work fine as long as you don't make a symbolic link between databases. Suppose that you have a database db1 under the MySQL data directory, and then make a symlink db2 that points to db1:
shell> cd /path/to/datadir shell> ln -s db1 db2
Now, for any table tbl_a in db1, there also appears to be a table tbl_a in db2. If one client updates db1.tbl_a and another client updates db2.tbl_a, there will be problems.
If you really need to do this, you can change one of the source files. The file to modify depends on your version of MySQL. For MySQL 4.0 and up, look for the following statement in the mysys/my_symlink.c file:
if (!(MyFlags & MY_RESOLVE_LINK) || (!lstat(filename,&stat_buff) && S_ISLNK(stat_buff.st_mode)))
Before MySQL 4.0, look for this statement in the mysys/mf_format.c file:
if (flag & 32 || (!lstat(to,&stat_buff) && S_ISLNK(stat_buff.st_mode)))
Change the statement to this:
if (1)
On Windows, you can use internal symbolic links to directories by compiling MySQL with -DUSE_SYMDIR. This allows you to put different databases on different disks. See Section 184.108.40.206, "Using Symbolic Links for Databases on Windows."
126.96.36.199 Using Symbolic Links for Tables on Unix
Before MySQL 4.0, you should not symlink tables unless you are very careful with them. The problem is that if you run ALTER TABLE, REPAIR TABLE, or OPTIMIZE TABLE on a symlinked table, the symlinks will be removed and replaced by the original files. This happens because these statements work by creating a temporary file in the database directory and replacing the original file with the temporary file when the statement operation is complete.
You should not symlink tables on systems that don't have a fully working realpath() call. (At least Linux and Solaris support realpath()). You can check whether your system supports symbolic links by issuing a SHOW VARIABLES LIKE 'have_symlink' statement.
In MySQL 4.0, symlinks are fully supported only for MyISAM tables. For other table types, you will probably get strange problems if you try to use symbolic links on files in the operating system with any of the preceding statements.
The handling of symbolic links for MyISAM tables in MySQL 4.0 works the following way:
In the data directory, you will always have the table definition file, the data file, and the index file. The data file and index file can be moved elsewhere and replaced in the data directory by symlinks. The definition file cannot.
You can symlink the data file and the index file independently to different directories.
The symlinking can be done manually from the command line with ln -s if mysqld is not running. With SQL, you can instruct the server to perform the symlinking by using the DATA DIRECTORY and INDEX DIRECTORY options to CREATE TABLE.
myisamchk will not replace a symlink with the data file or index file. It works directly on the file a symlink points to. Any temporary files are created in the directory where the data file or index file is located.
When you drop a table that is using symlinks, both the symlink and the file the symlink points to are dropped. This is a good reason why you should not run mysqld as root or allow users to have write access to the MySQL database directories.
If you rename a table with ALTER TABLE … RENAME and you don't move the table to another database, the symlinks in the database directory are renamed to the new names and the data file and index file are renamed accordingly.
If you use ALTER TABLE … RENAME to move a table to another database, the table is moved to the other database directory. The old symlinks and the files to which they pointed are deleted. In other words, the new table will not be symlinked.
If you are not using symlinks, you should use the –skip-symbolic-links option to mysqld to ensure that no one can use mysqld to drop or rename a file outside of the data directory.
SHOW CREATE TABLE doesn't report if a table has symbolic links prior to MySQL 4.0.15. This is also true for mysqldump, which uses SHOW CREATE TABLE to generate CREATE TABLE statements.
Table symlink operations that are not yet supported:
ALTER TABLE ignores the DATA DIRECTORY and INDEX DIRECTORY table options.
BACKUP TABLE and RESTORE TABLE don't respect symbolic links.
- The .frm file must never be a symbolic link (as indicated previously, only the data and index files can be symbolic links). Attempting to do this (for example, to make synonyms) will produce incorrect results. Suppose that you have a database db1 under the MySQL data directory, a table tbl1 in this database, and in the db1 directory you make a symlink tbl2 that points to tbl1:
shell> cd /path/to/datadir/db1 shell> ln -s tbl1.frm tbl2.frm shell> ln -s tbl1.MYD tbl2.MYD shell> ln -s tbl1.MYI tbl2.MYI
Now there will be problems if one thread reads db1.tbl1 and another thread updates db1.tbl2:
The query cache will be fooled (it will believe tbl1 has not been updated so will return out-of-date results).
ALTER statements on tbl2 will also fail.
126.96.36.199 Using Symbolic Links for Databases on Windows
Beginning with MySQL 3.23.16, the mysqld-max and mysql-max-nt servers for Windows are compiled with the -DUSE_SYMDIR option. This allows you to put a database directory on a different disk by setting up a symbolic link to it. This is similar to the way that symbolic links work on Unix, although the procedure for setting up the link is different.
As of MySQL 4.0, symbolic links are enabled by default. If you don't need them, you can disable them with the skip-symbolic-links option:
[mysqld] skip-symbolic-links
Before MySQL 4.0, symbolic links are disabled by default. To enable them, you should put the following entry in your my.cnf or my.ini file:
[mysqld] symbolic-links
On Windows, you make a symbolic link to a MySQL database by creating a file in the data directory that contains the path to the destination directory. The file should be named db_name.sym, where db_name is the database name.
Suppose that the MySQL data directory is C:mysqldata and you want to have database foo located at D:datafoo. Set up a symlink like this:
Make sure that the D:datafoo directory exists by creating it if necessary. If you already have a database directory named foo in the data directory, you should move it to D:data. Otherwise, the symbolic link will be ineffective. To avoid problems, the server should not be running when you move the database directory.
Create a file C:mysqldatafoo.sym that contains the pathname D:datafoo.
After that, all tables created in the database foo will be created in D:datafoo. Note that the symbolic link will not be used if a directory with the database name exists in the MySQL data directory.


text:
The Swim Course is quite unique in the world of Ironman races, as it covers two lakes, separated by a running passage of 200m. The passage is a great highlight for all spectators after cheering for the Ironman athletes the swim start. The Austria Ironman 70.3 starts in waves.
The bike course will cycle in a 90km round. Among the most interesting highlights count on one hand the beautiful Wachau, with ist enchanting vineyards, the apricot flowering time and the old castles. Beside the Wachau, our bike course leads you shortly after the transition area to the Austrian motorway S33. Where usually the cars drive with 130 km/h, the athletes copy them and speed up simply by the knowledge to drive on a highway. Moreover on the bike track can be found 2 aid stations, which wait before/after the two climbs Hollenburg and Aggsbach in Krustetten after 25km and 65km in Gansbach. At the Austria IRONMAN 70.3 St. Pölten there will be no self stations. Altitude bike: 1024m for 90km
You have to run two laps. Right out of the transition zone, the course will find it´s way for the first time into the new atmosphere of the IRONMILE, before the athletes take their way a long the waterfront of the Traisen. The way leads you to the modern architecture of the Lower Austrian government district. For the first time the course will beacon to the charming old-baroque town in St. Pölten. There we will build up an own aid station around the sidewalk of the St. Pölten cafés. Moreover the audience will find a new hotspot with gastronomic delicacies, the perfect area for spectators, family and friends which will whoop your own favorite. Along the Traisen the route (beacons) leads back to the Sport.Zentrum Lower Austria, where you will discover our new finishline.

subset: commoncrawl


text:
A&E's Obsessed documents the process in which people with various forms of OCD try to manage their conditions. On last night's episode, Russ — a Corky Sinclair-type — saw his pack-rat ways sever his "friendship" with a man named Rich.
Russ, an aspiring musical theater actor, developed an attachment to objects after the death of his mother left him without any family, and very few friends. An antiques enthusiast, he compulsively buys memorabilia and pieces of furniture that he can't even access because so much stuff is piled on them. He seems closeted (his clothes, shoes, and other clutter are anything but), and, even though he refers to Rich as his "friend" it's obvious that they actually used to date.
Russ' dream is to get his apartment and life in order, and buy a comfortable chair for Rich to sit on. He thinks this is a way to get Rich back in his life. After Russ completed 12 weeks of therapy for his condition, Rich came over for a visit, and although there was a huge improvement, Rich wasn't all that impressed... in fact, he didn't seem to care for the comfortable chair that Russ purchased.


text:
Find Our Latest Video Reviews on YouTube!
If you want to stay on top of all of our video reviews of the latest tech, be sure to check out and subscribe to the Gear Live YouTube channel, hosted by Andru Edwards! It's free!
Tuesday January 24, 2012 4:07 pm
Apple posts record-breaking holiday quarter results with $13 billion in sales
Posted by Andru Edwards - Categories: Apple, Corporate News
This afternoon, Apple announced that it has posted a record-breaking holiday quarter for fiscal Q1 2012, led by massive sales of iPhone, iPad, and Mac computers. In a nutshell, the company made a ton of cash, selling over 37 million iPhones, 15,430,000 iPads, 5,200,000 Macs, and 15,400,000 iPods. Full release after the jump.
Highest Quarterly Revenue and Earnings Ever
All-Time Record iPhone, iPad and Mac Sales
CUPERTINO, Calif.–(BUSINESS WIRE)–Apple® today announced financial results for its fiscal 2012 first quarter which spanned 14 weeks and ended December 31, 2011. The Company posted record quarterly revenue of $46.33 billion and record quarterly net profit of $13.06 billion, or $13.87 per diluted share. These results compare to revenue of $26.74 billion and net quarterly profit of $6 billion, or $6.43 per diluted share, in the year-ago quarter. Gross margin was 44.7 percent compared to 38.5 percent in the year-ago quarter. International sales accounted for 58 percent of the quarter's revenue.
"Apple's momentum is incredibly strong, and we have some amazing new products in the pipeline."
The Company sold 37.04 million iPhones in the quarter, representing 128 percent unit growth over the year-ago quarter. Apple sold 15.43 million iPads during the quarter, a 111 percent unit increase over the year-ago quarter. The Company sold 5.2 million Macs during the quarter, a 26 percent unit increase over the year-ago quarter. Apple sold 15.4 million iPods, a 21 percent unit decline from the year-ago quarter.
"We're thrilled with our outstanding results and record-breaking sales of iPhones, iPads and Macs," said Tim Cook, Apple's CEO. "Apple's momentum is incredibly strong, and we have some amazing new products in the pipeline."
"We are very happy to have generated over $17.5 billion in cash flow from operations during the December quarter," said Peter Oppenheimer, Apple's CFO. "Looking ahead to the second fiscal quarter of 2012, which will span 13 weeks, we expect revenue of about $32.5 billion and we expect diluted earnings per share of about $8.50."
- Related Tags:
- aapl, apple, apple earnings, apple investors, ipad, ipad 2, iphone, iphone 4s, ipod, ipod touch, mac, tim cook
Latest Gear Live Videos
- Subscribe:
- YouTube
- iTunes High Definition
- iTunes Standard Version
© Gear Live Inc. {year} – User-posted content, unless source is quoted, is licensed under a Creative Commons Public Domain License. Gear Live graphics, logos, designs, page headers, button icons, videos, articles, blogs, forums, scripts and other service names are the trademarks of Gear Live Inc.


text:
March 26 – What education did your mother receive? Your grandmothers? Great-grandmothers? Note any advanced degrees or special achievements.
I always remember my dear Mum being very proud that she won a Scholarship to attend a particular school when she was much younger. The war came along and interfered with Mum's education, especially as she was evacuated away from her home and family. She won a Junior County Scholarship that allowed her entry into a very good school and her own mum found it hard to believe that her daughter did so well.
I have no idea about the education received by both my grandmothers or any of my great grandmothers. I think this is something I need to look into, like school logs, as it might prove very interesting.
There is no family information passed down that has been specific about the education these female ancestors received and I have no knowledge of any degrees or special achievements attained by any of them.


text:
Fashion Films
Project Archive
Sign In | Register
Follow us
The Home of Fashion Film and Live Fashion Broadcasting
Shop Fashion
Shop Art
Fashion Films
Project Archive
Follow us
Recently Updated
Alphabetical A - Z
Alphabetical Z - A
Fashion Films
Guest Reports
Contemporary Art
Video Art
Behind The Scenes
Video Portraits
Paris Collections
Fashion Shoots
Gary Aspden, Lou Stoppard, Gary Warnett, Elgar Johnson, Mandi Lennard, Daryoush Haj-Najafi, Jason Evans, Stephen Mann and Jordan Weaver
May 24 2016
Motivated by the prevalence of sporty shapes on high fashion runways, SHOWstudio investigates the history of key 'sportswear' garments. Working on the ...
Alexandre de Betak
Betak: Fashion Show Revolution
Sep 29 2017
In keeping with SHOWstudio's longterm commitment to revealing the closed world of high fashion, SHOWstudio showcases a selection Art Director, Producer...
Nick Knight, Jon Jacobsen, Alex Box and Jonathon Luke Baker
Die Verwandlung
Sep 27 2017
Filmmaker and Director Jon Jacobsen presents his multifaceted project, created at SHOWstudio as part of a collaborative residency with the British Coun...
Nick Knight, Kylie Jenner, Anna Trevelyan, V Magazine, Lisa Eldridge, Martin Cullen, Riana Casson, Britt Lloyd and Raquel Couceiro
Jul 4 2017
SHOWstudio aims to reveal every part of the photographic process, from innovative sets and astute styling to unusual photography techniques and breatht...
Nick Knight, adidas, Goldie and Gary Aspden
adidas Originals x Spezial A/W 17
Sep 21 2017
For A/W 17, SPEZIAL continues to take inspiration from the enduring adidas legacy in sport and leisure, presenting a range of reimagined apparel pieces...
Nick Knight, Gareth Pugh, Val Garland, Sam McKnight, Younji Ku, Carson McColl, Britt Lloyd, Katie Shillingford, Roly Porter, Olivier de Sagazan, Andrew Tomlinson, Riana Casson, Rob Rusling and Marian Newman
Gareth Pugh S/S 18
Sep 16 2017
'This is not a show.' Nick Knight and Gareth Pugh offer an exclusive visual insight into Pugh's S/S 18 collection presented here as fashion film. In co...
Marie Schuller and Dice Kayek
My Name Is Eva And I Am A Witch
Sep 15 2017
Fashion filmmaker Marie Schuller presents 'My Name Is Eva And I Am A Witch', showcasing a selection of fashion from Parisian house Dice Kayek. In this ...
Nick Knight, Gareth Pugh, Carson McColl, Younji Ku, Britt Lloyd, Riana Casson and Peiman Zekavat
Gareth Pugh A/W 17
Sep 12 2017
Gareth Pugh's collection for A/W 17 presents a ferocious expression of female resistance in the form of monolithic, dexterous garments. Filmed amongst ...
Nick Knight, Tessa Kuragi, Tom Hingston, Rob Rusling, Lusha Alic, Marianne Maric, Marta Musial Rosalie Van Velsen, Anna Grodskaya, Narya Abhimata, Julia Comita, Rasa GV, Eloise Vene and Rasa Juskeviciute
Sep 6 2017
In celebration of Nick Knight's Mastered course, SHOWstudio presents a series of films and stills chosen by Tessa Kuragi and Tom Hingston and created b...
Nick Knight, Naomi Campbell, Liberty Ross, Gareth Pugh, Kanye West, Ruth Hogben, Nicola Formichetti, Daphne Guinness, Stephen Jones, Raquel Zimmermann, Henry Holland, Val Garland, Simon Foxton, Sam McKnight, Lily Donaldson, Marie Schuller, Maarten van der Horst, Ming Xi, Tim Blanks, Terence Koh, Simon Costin, Sibling, Shun Watanabe, Rei Nadal, Ryan McGinley, Nasir Mazhar, Matthew Williams, Lily Cole, Kim Jones, Karlie Kloss, Jun Takahashi, Jen Brill, Jay Massacret, Jac, Hayward, Hahn-Bin, Gary Card, Freja Beha Erichsen, Erin O'Connor, Erdem, Edward Enninful, Craig McDean, Cathy Horyn, Carine Roitfeld, Boudicca, Anna Trevelyan, Alice Rawsthorn, Alexander Fury, Alasdair McLellan, Void of Course, Alice Hawkins, Abbey Lee Kershaw, Louise Gray, Craig Lawrence, Peter Jensen, Katie Grand, Poppy de Villeneuve, Giles Deacon, Jonathan Kaye, Atsuko Kudo, Katy England, Christopher Kane, Christopher Shannon, Roksanda Ilincic, Iris van Herpen, Phoebe English, Lou Dalton, David Koma, Eugene Souleiman, Piers Atkinson, Mary Katrantzou, Michael van der Ham, Patti Wilson, Lindsey Wixson, Umit Benan, Lulu Kennedy, Rick Owens, Katie Eary, Bouchra Jarrar, Carri Munden, Fred Butler, Rupert Sanderson, David Gandy, Cara Delevingne, Camilla Morton, Judy Blame, Philip Treacy, Laura Bailey, Brix Smith-Start, MACHINE-A, Kali Uchis, Sebastiaan Pieter and Marian Newman
Fashion Mix
Nov 4 2011
SHOWstudio continues to celebrate the inextricable link between music and fashion by inviting fashion's great and good to compile their own 'greatest h...
Nick Knight and SHOWstudio
Aug 1 2017
Enjoy a whistle-stop tour through SHOWstudio's history. Our take on a 'best-of' showreel features a compilation of our most celebrated fashion films an...
Piers Atkinson, Jessica Broas, Lizzie McQuade, Rosie Beard, Philip Dunn, Kim Howells and Jordan Weaver
Flora: Piers Atkinson
Nov 12 2012
Milliner and renowned flower fan Piers Atkinson is the second creative to join SHOWstudio for a residency as part of our 'Flora' season. 'The Language ...
MACHINE-A, Stavros Karelis, Hyein Seo, Tom Zambaz, Younji Ku and Anna Trevelyan
Inside MACHINE-A
Jul 28 2017
Since 2004, SHOWstudio and cult concept store MACHINE-A have been a successful unity, continuously championing young designers and innovative ideas. 'I...
Georgina Evans and Reiner Holzemer
Jul 19 2017
'Dries' documents, for the first time ever, inspirational Belgian fashion designer Dries van Noten. For an entire year, director Reiner Holzemer docume...
Nick Knight, Vivienne Westwood, Alexander McQueen, Björk, Kanye West, Lady Gaga, Peter Saville, Tracey Emin, David Bailey, Juergen Teller, Wolfgang Tillmans and Travis Scott
In Camera
Feb 12 2003
Launched in 2003, 'In Camera' introduced a completely new premise to the interview format. Allowing a global online audience - as well as the interview...
Nick Knight, Rei Nadal, Sk8thing, Stavros Karelis, Toby Feltwell, Daryoush Haj-Najafi, C.E, Slam Jam, Rezzett, Riana Casson, Rezzett, Ali Michael and Raquel Couceiro
Untitled Project
Dec 10 2015
For over two years, Nick Knight, director Rei Nadal and the duo behind Cav Empt explored the term 'youth', documenting their stages of research in a SH...
Nick Knight, Parsons School of Design, Panisa Busayanont, Chenghui Zhang, Jihyun Myung and Georgina Evans
SHOWstudio x Parsons
May 24 2017
Combining a mutual passion in the championing of fashion film as a medium, SHOWstudio and New York's Parsons School of Design collaborate on a competit...
Nick Knight, Lou Stoppard, Phoebe English, Adam Mansell, Tamara Cincik, Munira Mirza, Karen Binns, Eszter Kantor, Samuel Nicholls and Navjyot Lehl
Brexit: The Impact on the Fashion Industry
May 23 2017
In-keeping with SHOWstudio's ethos of international awareness and our reach to a global audience, Nick Knight opens conversation into the repercussions...
Nick Knight, V Magazine, Katy England, Lisa Eldridge, Sara Grace Wallerstedt, Riana Casson, Malcolm Edwards and Cecily Cracroft-Eley
May 8 2017
Nick Knight and Katy England unite once again to capture a cornucopia of couture and crochet for V Magazine. Sara Grace Wallerstedt is enlaced in a fea...
Raquel Couceiro, Rei Nadal, Nicholas Kirkwood, PRETTYBIRD, Britt Lloyd and Jess Maybury
Dark Matter
May 7 2017
For his A/W 17 collection, forward-thinking footwear designer Nicholas Kirkwood tapped director Rei Nadal to create a promotional fashion film. The col...
Nick Knight, Kate Moss, Naomi Campbell, Liberty Ross, Kristen McMenamy, Lily Cole, Erin O'Connor, Alek Wek, Karen Elson, Guinevere van Seenus, Winnie Harlow, Pat Cleveland and Amber Valletta
Apr 30 2014
Nick Knight and SHOWstudio present the history of contemporary fashion photography as told from the subjects' perspectives. When envisaging 'Subjective...
Nick Knight, KANGHYUK, D /ARK, H. LORENZO, Gabriel Carasso, Lara Johnson-Wheeler, Raquel Couceiro, Stavros Karelis and Harry Fisher
Apr 27 2017
As part of a brand new collaboration, SHOWstudio are proud to present the work of MACHINE-A and Stavros Karelis's latest find, the pioneering graduate ...
Balenciaga, mytheresa.com, 25 Magazine, Gordon von Steiner, Katja Mayer, Miguel Bento, Melissa Tofton, Yasmina Dexter, Anna Pesonen, Feast Films, Hettie Griffiths, Rob Jarvis, Christos Petritzis, Uli-K, Ross Westland, Joseph J Marshall, Faze Miyake, Emma Westenberg, Sophie Hardeman, C.E, Miu Miu and Caitlin Price
Fashion Film Exclusives
Feb 20 2016
As the home of fashion film, SHOWstudio debuts and supports various works that explore the possibilities of the medium. Some whimsical, some avant gard...
Alice Hawkins
Alice's Adventures
Feb 1 2013
Explore Alice Hawkins' magical world with these exclusive scans. Taken from the photographer and filmmaker's personal creative diaries, the pages featu...
Isamaya Ffrench, QIC Global Real Estate, Bistrotheque and Stuart Miller
Ffrench Pharmaceuticals
Mar 27 2017
For its second year running, Ffrench Pharmaceuticals travels to Hong Kong Art Basel 2017 to see make-up doyenne Isamaya Ffrench, QIC Global Real Estate...
Nick Knight, Gareth Pugh, Rei Nadal, Raquel Couceiro, Georgina Evans, Lara Johnson-Wheeler and Layla Sailor
Mar 27 2017
Constructed seeks to exhibit the growing medium of fashion film within China whilst examining the faculty for contemporary artists to express themselve...
Nick Knight, Christian Krug, Julia von Boehm, Madison Stubbington, Lisa Eldridge, Stern, Jazzelle Zanaughtti, Anna Cleveland, Eamonn Hughes, Andrew Tomlinson, Raquel Couceiro, Gabriel Carasso, Riana Casson, Britt Lloyd and Akira Morgan
Ungewöhnlich Schön
Feb 22 2017
In December 2016, Nick Knight shot a selection of key looks from the S/S 17 collections exclusively for German publication Stern magazine. Knight worke...
Nick Knight, Travis Scott, Numéro, Riana Casson and Numéro Homme
Mar 6 2017
Building on their previous creative collaboration, Nick Knight unites with rapper Travis Scott once again for the cover story of Numéro Magazine's 33rd...
adidas, Gary Aspden, Nick Griffiths, &SON and Chronixx
adidas Originals x SPEZIAL S/S 17
Feb 27 2017
Celebrating the launch of the S/S 17 SPEZIAL collection, Gary Aspden, Nick Griffiths and &SON offer a short film set to music composed by Matthieu Bost...
Nick Knight, Matthew Williams, Paul Hetherington, ALYX, NOLIFE and Raquel Couceiro
Natural Order: Alyx A/W 16
Feb 27 2017
For the presentation of Alyx's A/W 16 collection, Nick Knight and Matthew Williams explore the chaos inherent in nature. Model Stella Lucia appears bot...
Nick Knight, Beats by Dre, Omar Johnson, Younji Ku, Jon Emmony, NOLIFE, Demi Scott, Tino Kamal and PRETTYBIRD
New Space
Jan 26 2017
This Nick Knight film, in collaboration with Beats by Dre, comments on the world's multi-faceted and multi-sensory influences and experiences. Knight's...
Shaun Leane and Foxall Studio
18 Woodstock Street
Jan 20 2017
Jeweller Shaun Leane's first foray into fashion film, entitled '18 Woodstock Street', sees Leane's jewellery in motion. Made in collaboration with Foxa...
Rei Nadal, Stavros Karelis, PRETTYBIRD, DELADA and Raquel Couceiro
Jan 5 2017
Commissioned by MACHINE-A's Stavros Karelis, Rei Nadal's latest film for DELADA showcases their A/W 17 collection and its multi-material, patchwork sty...
Simone Rocha, Rob Rusling and Gabriel Carasso
Design Download: Simone Rocha
Dec 25 2016
For our eleventh Design Download, SHOWstudio teams with Simone Rocha, winner of the British Womenswear Designer award at the 2016 British Fashion Award...
Nick Knight, Sam McKnight, Tom Ford, Mica Arganaraz and Carine Roitfeld
Black Orchid 2016
Dec 21 2016
Nick Knight's 2016 fashion film for Tom Ford's iconic Black Orchid fragrance sees model of the moment Mica Arganaraz enveloped in a billowing burst of ...
Gareth Pugh, Stephen Jones, Simon Foxton, Adam Murray, Lou Stoppard, Jon Emmony, Claire Barrow, Ben Whyman, Jamie Hawkesworth, Nina Manandhar, Open Eye Gallery, Liverpool John Moores University, Adrian Green, Helen Smith, Michael Kenny, Yara Heine, Christopher Shannon, Gary Aspden, Thom Murphy, Tom Zambaz and Katie Hindle
Jul 3 2016
'The skill will be in learning to look beneath the clichés and habits of imagination that lie at the heart of these myths.' Motivated by questioning ex...
Natasha Garoosi, Wendy Bowman, Alexandra Gavillet and Lara Johnson-Wheeler
Dec 15 2016
#UNMUTED presents a series of films directed by Alexandra Gavillet. Shot by Wendy Bowman and produced by Natasha Garoosi, the films aim to promote comm...
Ronan Mckenzie and Georgina Evans
Hard Ears
Dec 7 2016
Launched in December 2016, HARD EARS is photographer Ronan Mckenzie's debut publication. HARD EARS' first issue is a collection of text and imagery ins...
Nick Knight, Charlotte Stockdale, Clemence Lobert, Raquel Couceiro, Phoebe Arnold, British Fashion Council and Travis Scott
Dec 1 2016
Nick Knight's vision of current and contemporary fashion are reflected in 'Up' and '90210', fashion films created for the 2016 British Fashion Awards. ...
Nick Knight, Caitin Stickels, Jacob K, V Magazine, Laura Dominique, Andrew Tomlinson, Martin Cullen, Younji Ku and Riana Casson
Portrait of Caitin Stickels
Nov 16 2016
After discovering her on Instagram, Nick Knight invited Caitin Stickels to model for V Magazine. Born with rare chromosomal disorder, Cat Eye Syndrome,...
Nick Knight, Demi Scott, V Magazine, Jacob K and Andrew Tomlinson
Demi Couture
Nov 7 2016
'Grace isn't something that comes from class or breeding, it's innate and comes from a certain sense of self. It's egalitarian.' To Nick Knight, model ...
Nick Knight, Faustine Steinmetz, Niamh White and Raquel Couceiro
Faustine Steinmetz: Sculpting Denim
May 28 2015
Continuing our tradition of inviting a designer to take up residence in our studio and make a garment live on camera, we invited rising star and denim ...
Nick Knight, Wolf Gillespie, adidas and Gary Aspden
adidas Originals x SPEZIAL A/W 16
Sep 19 2016
To celebrate the return of adidas SPEZIAL for A/W 16, Gary Aspden asked Nick Knight to capture the new collection. Starring Wolf Gillespie, son of styl...
Fiona Gourlay, Tobie Giddio, Conrad Roset, Joshua Osborn, Cecilia Carlstedt, Marco Rea, Gill Button, Fahren Feingold, Blair Breitenstein, Jenifer Corker, Connie Gray, Bex Cassie and Gray M.C.A
Drawing On Style
Sep 15 2016
In collaboration with historical fashion illustration experts Gray M.C.A, SHOWstudio presents 'Drawing On Style', an exhibition showcasing original fas...
Nick Knight and Daelim Museum
Nick Knight: Image
Oct 6 2016
From 6 October 2016, Daelim Museum presents 'Nick Knight: Image', Knight's first solo show. The exhibition features over 100 works and installations, h...
Nick Knight, Katie Shillingford, Isamaya Ffrench, Jazzelle Zanaughtti, AnOther, Younji Ku, 0044 and Riana Casson
Comme des Garçons
Sep 9 2016
Nick Knight and stylist Katie Shillingford unite to celebrate key pieces from Comme des Garçons' A/W 16 collection. Rei Kawakubo's bubblegum pinks and ...
Nick Knight, Helen Bullock, Alina Zamanova, Amelie Hegardt, Jenifer Corker, Rei Nadal, Richard Kilroy, Valerie Servais, Velwyn Yossy, Stephen Doherty, Bex Cassie, Frida Wannerberger, Gill Button, Samuel Harrison, Jacquetta Crook, Joshua Osborn, Connie Lim, Stephan Beaumont One Eye Girl, Cecilia Carlstedt, Nicasio Torres Melgar, Alessandra Genualdo, Yasmin Wijnaldum, Molly Bair, Ruth Bell, Julia Banas, Selena Forrest, Chaos Fashion, Jazzelle Zanaughtti, Riana Casson, Alina Stashinova, GARAGE Magazine, Raquel Couceiro and Gabriel Carasso
Jun 30 2016
On 30 June and 1 July 2016, SHOWstudio undertook its first ever Facebook Live broadcast. The stream, a collaboration with GARAGE Magazine, encompasses ...
Eva Losada Membibre, Rei Nadal, Stavros Karelis, Ellie Grace Cumming, DELADA, Raquel Couceiro and PRETTYBIRD
Sep 2 2016
Director Rei Nadal's fashion film, created exclusively for SHOWstudio and MACHINE-A, features DELADA's first full collection. The range was inspired by...
Page 2 of 13
Previous page
Next page


text:
Today was the deadline for the Cardinals, and they've shoen to go without Kevin Kolb.
A league source tells PFT's Mike Florio that Kolb rejected the Cards' offer of a pay cut, and that he'll be released. The door remains open for a return, but they had to make a decision by 4 p.m. before a $2 million roster bonus was due.
Frankly, the writing was on the wall for Kolb the minute they brought Drew Stanton in. While it's hard to give a player such as Stanton the keys to the car sight unseen, it's also hard to commit financially to Kolb, who never met expectations after the Cardinals traded and invested heavily in him.


text:
|UTG pass
Click here to visit site
|Short review: Three websites for the cost of one is an offer not to be sniffed at, here you've got 3 top shemale internet sites, a mix of hard-core and solos, galleries and movies, a top-model index and regular updates. And all this comes from a top pornography producer so you also get a great service, easy navigation, well designed websites and some of the top top-models working in dicky girl pornographic. You also have flawless value for money.