Indexes in Teradata - teradata

How to Enable/Disable Indexes in TERADATA Database?
I want to disable indexes and do update and then enable the indexes in Teradata.
If Enable/Disable option not available in Teradata, in the sense How can I achieve this ? If I use DROP Indexes, how can I recreate the indexes for all the tables?

Teradata gives you a way to create a table without choosing for primary index (if you are sure of any column).
You can create table with No primary Index. Here is a sample of how to do so:
Create table <table name>
(<columnname> <datatype>,
<columnname> <datatype>)
no primary index ;

Teradata does not have a disable index feature.
All tables have a Primary Index (PI) which is chosen by the RDBMS unless you specify one.
CREATE INDEX <index name> (<column list>) ON table name;
CREATE UNIQUE INDEX (department) ON tbl_employee;
DROP INDEX ind_dept ON tbl_employee;
DROP INDEX (department,emp_number) ON tbl_employee;

In Teradata you can't drop Primary index of a table. The primary index defines where data will reside and which AMP receives the row.
To alter the primary index of a table you need to delete all the records from the table ( As data is already distributed by the row hash value of the PI) then only you can change the primary index of a table by using below command:-
Alter table table_name modify primary index index_name (column list);
Steps to achieve your goal
You can crate a new table with your desired index ( temp, wrk, intermediate table) insert the records from the original table and update the wrk table.
delete the original table and insert the wrk table data.
And you are done.

Create & Drop index is the only option you have here

Simple answer - you can't disable and re-enable indexes in Teradata.
However, there some workarounds.
Drop Index
If you talking about PI (primary index) - you can't drop it. All you can do is to make a copy of a table without an index.
You can drop secondary index though. Then simply create it again when you need it.
Drop-Create Table
This doesn't fit all cases, but often this is the fastest way to do the work, especially if the issue you have is with PI.
BTW: it is not clear, why would you need to do that? Performance or logic or something else? That probably will affect recommendation.

Since you did not specify what kind of index you want to disable/enable, below are the approach you can follow on either cases.
PRIMARY INDEX
CREATE a new table with the same PI
INSERT the updated data to new table
DROP the old table - DROP TABLE <OldTable>;
RENAME the new table same as the old one. - RENAME TABLE <NewTable> TO <OldTable>;
Above recommendation for Primary Index is only applicable if you are going to update a primary index column value. If you will update other columns (not the PI column) then you can just issue an UPDATE Statement directly.
SECONDARY INDEX
DROP the SI - DROP INDEX <IndexName> ON <TableName>;
UPDATE table data
RECREATE the SI - CREATE INDEX <IndexName> (<ColumnList>) ON <TableName>;

Related

Adapt ON CONFLICT clause to new unique index?

I want to add an extra unique constraint to an existing table. This and other answers say it's not possible with sqlite, and suggest creating an unique index:
ALTER TABLE example ADD COLUMN new_unique TEXT;
CREATE UNIQUE INDEX new_unique_index ON example(new_unique);
This seems to work. However, I'm having trouble with UPSERTs:
INSERT INTO example (foo, old_unique, new_unique) VALUES ('foo', 'old', 'new') ON CONFLICT(old_unique, new_unique) DO UPDATE SET foo='foo';
This gives an error:
ON CONFLICT cause does not match any PRIMARY KEY or UNIQUE constraint
Is there any way I could adapt the ON CONFLICT clause of the statement above to work with the new "constraint"?
I tried using new_unique_index, to no avail. If it's impossible, is there any alternative to creating a new table with the new unique constraint and copying the values from the old table into the new one with NULL for the new constraint column? This would be burdensome. I imagine I could create a new table with all of the former's columns, except the old uniques, plus the new unique, and link them somehow, but it sounds messy and I have no idea how to proceed.
Minimum reproducible example:
CREATE TABLE example (foo TEXT, old_unique TEXT, UNIQUE(old_unique));
ALTER TABLE example ADD COLUMN new_unique TEXT;
CREATE UNIQUE INDEX new_unique_index ON example(new_unique);
INSERT INTO example (foo, old_unique, new_unique) VALUES ('foo', 'old', 'new') ON CONFLICT(old_unique, new_unique) DO UPDATE SET foo='foo';
Is there any way I could adapt the ON CONFLICT clause of the statement above to work with the new "constraint"?
(old_unique, new_unique) is a not a possible constraint target as there is no index that combines both columns, each is an individual constraint (so you could use one or the other, as my understanding is that you are limited to a single UPSERT clause and a single conflict target).
If instead of :-
CREATE UNIQUE INDEX new_unique_index ON example(new_unique);
You used
CREATE UNIQUE INDEX new_unique_index ON example(old_unique,new_unique);
Then the following will work :-
INSERT INTO example (foo,old_unique,new_unique) VALUES('foo','old','new') ON CONFLICT (old_unique,new_unique) DO UPDATE SET foo = 'foo';
(well at least not be rejected due to no covering primary key or index for the given conflict target).
If it's impossible, is there any alternative to creating a new table with the new unique constraint and copying the values from the old table into the new one with NULL for the new constraint column? This would be burdensome.
It's not really burdensome e.g. you could use :-
CREATE TABLE IF NOT EXISTS temp_example (foo, old_unique,new_unique, UNIQUE(old_unique,new_unique));
INSERT INTO temp_example SELECT *,null FROM example;
ALTER TABLE example RENAME TO old_example;
ALTER TABLE temp_example RENAME TO example;
DROP TABLE If EXISTS old_example;
i.e. as you are adding a column and it will be the last column then there is no need to code column names.

Alter table to change the size of index

I need to enlarge the varchar of one column from 64 to 80. The table is quite big(9m rows). One point that make the alter uncertain is that the column is also indexed.
So if I alter the column, since the column is one of the indexes, will any locking happen for row or table?
Thanks.
Not sure about locking part. but standard recommendation would be to drop the index first and then alter table and again create the index.
drop index [[index name]]
go
alter table t1 [[alter column]]
go
create index [[index name]]
go

xcode delete a column for a sql database

Is it possible to delete a column from an SQLlite database. I have Googled this and it seems to be impossible.
From the ALTER TABLE manual;
SQLite supports a limited subset of ALTER TABLE. The ALTER TABLE command in SQLite allows the user to rename a table or to add a new column to an existing table. It is not possible to rename a column, remove a column, or add or remove constraints from a table.
So, no, not without dropping and recreating the table.
According to the docs:
It is not possible to rename a column, remove a column, or add or
remove constraints from a table.
I guess it has to be done manually.

Bulk update of column values of entire table

We have an Oracle 11g database table with around 35 million rows. We are in a situation where we have to update all values of one column. This column is indexed.
I have a script that can generate the updated values and can populate it in a text file.
I'm looking for a good strategy to do a bulk update to this table. We can afford a downtime of around 10 hours.
Will it be a good idea to
Dump the entire table to a flat file
Update the values using any scripting language
Reload the entire table
Rebuild indexes
What are the pitfalls that one can encounter?
I'm not competent in PL/SQL. Is there a way to solve this in PL/SQL or any way "within" the database itself?
Thanks,
Prabhu
The fastest way will probably be to create an external table based on your flat file of update values and then:
create table new_table as
select o.col1, o.col2, o.col3, ..., x.value as colN
from old_table o
join extern_table x on ...;
(Make sure that join returns all the rows from old_table. The join may need to be an outer join.)
-- drop foreign key constraints that reference old_table
alter table child1 drop constraint fk_to_old_table1;
...
drop table old_table;
rename new_table to old_table;
-- Re-create indexes and constraints on old_table
alter table old_table add constraint oldpk primary key (col1);
...
-- Re-create the dropped foreign key constraints to old_table
alter table child1 add constraint fk_to_old_table1 ...;
...

SQLITE: Unable to remove an unnamed primary key

I have a sqlite table that was originally created with:
PRIMARY KEY (`column`);
I now need to remove that primary key and create a new one. Creating a new one is easy, but removing the original seems to be the hard part. If I do
.indices tablename
I don't get the primary key. Some programs show the primary key as
Indexes: 1
[] PRIMARY
The index name is typically in the [].
Any ideas?
You can't.
PRAGMA INDEX_LIST('MyTable');
will give you a list of indices. This will include the automatically generated index for the primary key which will be called something like 'sqlite_autoindex_MyTable_1'.
But unfortunately you cannot drop this index...
sqlite> drop index sqlite_autoindex_MyTable_1;
SQL error: index associated with UNIQUE or PRIMARY KEY constraint cannot be dropped
All you can do is re-create the table without the primary key.
I the database glossary; a primary-key is a type of index where the index order is typically results in the physical ordering of the raw database records. That said any database engine that allows the primary key to be changed is likely reordering the database... so most do not and the operation is up to the programmer to create a script to rename the table and create a new one. So if you want to change the PK there is no magic SQL.
select * from sqlite_master;
table|x|x|2|CREATE TABLE x (a text, b text, primary key (`a`))
index|sqlite_autoindex_x_1|x|3|
You'll see that the second row returned from my quick hack has the index name in the second column, and the table name in the third. Try seeing if that name is anything useful.

Resources