473,394 Members | 1,813 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Index disabled after TRUNCATE

I have a series of tables in which the data can be refreshed from a file.

Before refreshing the data, some of the tables are cleared using either TRUNCATE or DELETE.

If TRUNCATE is used, any index which is not PRIMARY or UNIQUE appears to be disabled and is not updated when new data is inserted into the table.

Performing an OPTIMIZE reactivates the index.

If DELETE is used instead of TRUNCATE, this problem does not occur.

Does anyone know if this a fault, a feature, an option which can be changed?

MySQL version 4.1.20
May 24 '07 #1
15 7199
pbmods
5,821 Expert 4TB
This probably has something to with the fact that TRUNCATE actually drops and recreates the table. It does not seem like it is supposed to do that, though, and I wasn't able to Google much about it. Try to see if you can reliably reproduce this behavior in a separate database.

You should also be able to re-enable the indexes by doing:

Expand|Select|Wrap|Line Numbers
  1. ALTER TABLE `tablename` ENABLE KEYS
  2.  
May 25 '07 #2
Motoma
3,237 Expert 2GB
MySQL 4.1 has a lot of quirky 'features' in it. I would suggest upgrading to 5.
May 25 '07 #3
MySQL 4.1 has a lot of quirky 'features' in it. I would suggest upgrading to 5.
Thanks for the advice, but not currently an option.

I'm running on a shared hosting system and because I was losing several indexes, my queries started performing badly (MySQL server overload), and my MySQL database was turned off - twice!

It was only after the second occurrence that I managed to get enough information to find out what was causing the problem.

Oh, and I have only just recently signed up with this host - the previous one suspended my account completely (e-mail, web, FTP, My SQL), again for MySQL server overload, presumably for the same reason.

I have a workround now, but you can see why I'm keen to understand the cause.
May 25 '07 #4
Motoma
3,237 Expert 2GB
I have been in the same boat. It is really frustrating when you have to use an outdated version of MySQL, especially if you are stuck with one that does not support stored procedures or subqueries.
May 26 '07 #5
This probably has something to with the fact that TRUNCATE actually drops and recreates the table. It does not seem like it is supposed to do that, though, and I wasn't able to Google much about it. Try to see if you can reliably reproduce this behavior in a separate database.

You should also be able to re-enable the indexes by doing:

Expand|Select|Wrap|Line Numbers
  1. ALTER TABLE `tablename` ENABLE KEYS
  2.  
After experimenting, it is not the TRUNCATE which disables the INDEXes - they are not activated from the time of the CREATE TABLE.

I created a copy of my table in another database.

There is a PRIMARY INDEX, a UNIQUE INDEX and 5 other INDEXes.

Running an OPTIMIZE TABLE or ANALYZE TABLE on the empty table returns 'Table is already up to date'.

INSERT INTO one or more rows and the PRIMARY INDEX and UNIQUE INDEX are updated - the other INDEXes are not.

ALTER TABLE `tablename` ENABLE KEYS has no effect .
Perhaps the INDEXES are not 'disabled', but they are certainly not active.

The only actions that seems to activate the INDEXes is OPTIMIZE TABLE or ANALYZE TABLE.

Once one of these is done, the INDEXes are maintained after any UPDATE, INSERT or DELETE.

TRUNCATE obviously drops and creates the table, and everything starts again.

Confused...
May 26 '07 #6
Motoma
3,237 Expert 2GB
Could you build a simple test case that demonstrates this behavior? I would like to test this out, if you could write up the SQL statements starting from your create table, I would be very appreciative.
May 26 '07 #7
Could you build a simple test case that demonstrates this behavior? I would like to test this out, if you could write up the SQL statements starting from your create table, I would be very appreciative.
I discarded the scripts and the data that I used to perform the test, but it was based on the table that had originally caused me the problem. There were 35 columns in this table, and some of it was sensitive data.

I will look at recreating a simple test case when I get chance, possibly later today.
May 29 '07 #8
Test case, simplified to the minimum below: -

Expand|Select|Wrap|Line Numbers
  1. DROP TABLE IF EXISTS Tester;
  2.  
  3. CREATE TABLE Tester
  4. (
  5.  ID INT(11) NOT NULL,
  6.  F1 VARCHAR(10) NOT NULL,
  7.  F2 VARCHAR(10) NOT NULL,
  8.  F3 VARCHAR(10) NOT NULL,
  9.  F4 VARCHAR(10) NOT NULL,
  10.  F5 DATETIME NOT NULL,
  11.  F6 TEXT NOT NULL,
  12.  PRIMARY KEY (ID),
  13.  UNIQUE I1 (F1, F2),
  14.  KEY I2 (F3, F4),
  15.  KEY I3 (F4),
  16.  KEY I4 (F1, F3, F4),
  17.  KEY I5 (F1, F4),
  18.  KEY I6 (F5)
  19. )
  20. TYPE = MYISAM;
Expand|Select|Wrap|Line Numbers
  1. SHOW INDEX FROM Tester;
Result: (PRIMARY and I1 cardinality 0; I2, I3, I4, I5, I6 cardinality NULL)

Expand|Select|Wrap|Line Numbers
  1. INSERT INTO Tester VALUES ('1', 'A1', 'A2', 'A3', 'A4', '2007-05-29', 'A5');
Expand|Select|Wrap|Line Numbers
  1. SHOW INDEX FROM Tester;
Result: (PRIMARY and I1 cardinality 1; I2, I3, I4, I5, I6 cardinality NULL)

Expand|Select|Wrap|Line Numbers
  1. OPTIMIZE TABLE Tester;
Expand|Select|Wrap|Line Numbers
  1. SHOW INDEX FROM Tester;
Result: (PRIMARY, I1, I2, I3, I4, I5, I6 all cardinality 1)
Note: ANALYZE TABLE Tester; has the same effect as OPTIMIZE TABLE Tester;

Expand|Select|Wrap|Line Numbers
  1. INSERT INTO Tester VALUES ('2', 'B1', 'B2', 'B3', 'B4', '2007-05-29', 'B5');
Expand|Select|Wrap|Line Numbers
  1. SHOW INDEX FROM Tester;
Result: (PRIMARY, I1, I2, I3, I4, I5, I6 all cardinality 2)
May 29 '07 #9
Motoma
3,237 Expert 2GB
Thank you. I was able to reproduce this behavior in MySQL 4.0.16-nt.
One thing I noticed, however, this behavior is not present with the InnoDB database engine.
May 29 '07 #10
pbmods
5,821 Expert 4TB
Cardinality is an estimated value, which MySQL uses to determine whether to use an index (and which index to use) or do a full scan. Even after running ANALYZE (or OPTIMIZE) TABLE, the index cardinality might not be correct even for small tables. This has to do with how MySQL calculates cardinality (hint: it doesn't run through and count all the unique values).

http://dev.mysql.com/doc/refman/5.0/en/show-index.html
May 29 '07 #11
Motoma
3,237 Expert 2GB
Try this out:

Expand|Select|Wrap|Line Numbers
  1. DROP TABLE IF EXISTS Tester;
  2. CREATE TABLE Tester
  3. (
  4. ID INT(11) NOT NULL AUTO_INCREMENT,
  5. K VARCHAR(10),
  6. U VARCHAR(1),
  7. PRIMARY KEY(ID),
  8. UNIQUE I1 (U),
  9. KEY K1 (K)
  10. )
  11. TYPE = MyISAM;
  12.  
  13. INSERT INTO Tester (K, U) VALUES ('2', '3');
  14. INSERT INTO Tester (K, U) VALUES ('2', '3');
  15. SHOW INDEX FROM Tester;
  16.  
I am not allowed to insert the second row, which leads me to believe the key is being enforced. I would be interested in hearing your ideas on this matter.
May 29 '07 #12
Cardinality is an estimated value, which MySQL uses to determine whether to use an index (and which index to use) or do a full scan. Even after running ANALYZE (or OPTIMIZE) TABLE, the index cardinality might not be correct even for small tables. This has to do with how MySQL calculates cardinality (hint: it doesn't run through and count all the unique values).

http://dev.mysql.com/doc/refman/5.0/en/show-index.html
My test case used only 2 rows, but in my live environment, the same results were there even after inserting more than 2,500 rows.

If MySQL determines its SQL execution plan based on what it knows about index cardinality and it sees NULL, then whether the index is present or not, this would cause the problem I was experiencing. Not too much of an overhead when processing a single table, but my code included multiple tables including a self join on this 2,500 row table.

The documentation for SHOW INDEX implies that ANALYZE TABLE (and I believe also OPTIMIZE TABLE) initially populates the cardinality of an index, but it also seems to be maintained thereafter (accurately in my experience) after every insert, update, delete.

My tables in this database are rebuilt regularly, and the fact that an ANALYZE is needed to activate the index is probably all I need to know to make sure I don't fall into the same trap again.
May 30 '07 #13
Try this out:

Expand|Select|Wrap|Line Numbers
  1. DROP TABLE IF EXISTS Tester;
  2. CREATE TABLE Tester
  3. (
  4. ID INT(11) NOT NULL AUTO_INCREMENT,
  5. K VARCHAR(10),
  6. U VARCHAR(1),
  7. PRIMARY KEY(ID),
  8. UNIQUE I1 (U),
  9. KEY K1 (K)
  10. )
  11. TYPE = MyISAM;
  12.  
  13. INSERT INTO Tester (K, U) VALUES ('2', '3');
  14. INSERT INTO Tester (K, U) VALUES ('2', '3');
  15. SHOW INDEX FROM Tester;
  16.  
I am not allowed to insert the second row, which leads me to believe the key is being enforced. I would be interested in hearing your ideas on this matter.
Yes, I agree, the uniqueness of index I1 is enforced, but the cardinality still shows as null. This implies to me that the index is present, but it's no use unless My SQL knows about it when it determines the best execution plan.
May 30 '07 #14
Motoma
3,237 Expert 2GB
Yes, I agree, the uniqueness of index I1 is enforced, but the cardinality still shows as null. This implies to me that the index is present, but it's no use unless My SQL knows about it when it determines the best execution plan.
This may be the case; have you tried running an EXPLAIN to see if the index is being used in that circumstance?
May 30 '07 #15
This may be the case; have you tried running an EXPLAIN to see if the index is being used in that circumstance?
No, I hadn't run an EXPLAIN on the query, but I have now, using phpMyAdmin.

Firstly, I ran an EXPLAIN on the query with the tables optimized.
Then, I reloaded my data (which performs a TRUNCATE first), and ran the EXPLAIN again.
(Followed very quickly by optimizing all the tables again!)

I was not familiar with the output of EXPLAIN for MySQL, but having read the documentation, my interpretation is as follows.

In both cases, the non-unique keys that I would expect to be used are listed under 'possible_keys'.

In an optimized state, for each reference to the table, one of the non-unique keys is listed under 'key' - the non-unique indexes would be used.

In a non-optimized state, for each reference to the table, only the unique index is shown under 'key' - the non-unique indexes would not be used.
May 30 '07 #16

Sign in to post your reply or Sign up for a free account.

Similar topics

4
by: Patrick L. Nolan | last post by:
Our Tkinter application has a big ScrolledText widget which is a log of everything that happens. In order to prevent people from making changes, we have it in DISABLED mode except when the...
0
by: Rafal Kedziorski | last post by:
hi, I have this table: CREATE TABLE `category_tree` ( `category_tree_id` BIGINT NOT NULL AUTO_INCREMENT, `parent_id` BIGINT, `mandant_id` SMALLINT NOT NULL,...
1
by: David Wake | last post by:
I have two radio buttons and two checkboxes in a form. I'm trying to write some code so that when a radio button is selected, its corresponding checkbox is disabled. My code looks like this: ...
6
by: Stu Carter | last post by:
Hi, I have an aspx page where some controls are initially disabled by the code-behind 'Page_Load' event. I want these controls to be dynamically enabled when the user checks a checkbox. ...
2
by: Hervé Piedvache | last post by:
Bug or problem with PostgreSQL ? version --------------------------------------------------------------- PostgreSQL 7.4.3 on i686-pc-linux-gnu, compiled by GCC 2.95.4 select * from my_table;...
1
by: rcamarda | last post by:
As part of my data warehouse nightly build, I truncate my tables in my target database. As example, I find it is much quicker to do a bulk API load of 13M records and to do an update/insert of...
2
by: rhepsi | last post by:
Hii all, I have a project where before i upload the data from 1st database to 2nd database, im truncating the 2nd database and then trying to upload... In this process, wat i found was that:...
0
by: Eric Davidson | last post by:
I am try to find a way to get load to reject a record if the data is too large and not just truncate it. eg. c:\temp\fred3.txt ------ a23456789012345678901234567890...
5
by: Timothy Madden | last post by:
Hello I see there is now why to truncate a file (in C or C++) and that I have to use platform-specific functions for truncating files. Anyone knows why ? I mean C/C++ evolved over many years...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.