Does the drop_partition command ignore foreign key dependencies? - vertica

Given table A with column (A1, A2, A3...) and table B with column (B1, B2, A1) where A1 is a foreign key on field A1 in table A.
Table A contains records that are referenced by B.
Tables are partitioned by a date field, and the field has the same value for related records in table A and B.
If a partition is dropped that contains a row in A that is referenced by B, why do I not get an exception? I would have expected some kind of error indicating that the record is being referenced somewhere.
Or am I missing something - should it be warning me?

Prior to version 8, Vertica can not enforce primary, unique or foreign key constraints during dml operations. You would have to detect the violation after the fact using analyze_constraints().
Even version 8 has limitations in this regard. First, you have to make sure the checking is enabled. Secondly, this only works for primary and uniques keys.
In order to enforce FK (on either version), you have to create a prejoin projection. However, even doing this is may not be your answer because you can't drop partitions when there is a prejoin projection (you'll have drop the prejoin projection, drop partitions, recreate the prejoin projection).
Also there are some other limitations to using prejoin projections.
I'll also mention that Vertica is not OLTP, it's focus is on fast loading and fast queries (and compression). I understand your pain, though, as occasionally I do need functionality like this.
Hope this helps.

Related

Replace foreign key column with compressed index

I would like to spare some tables in my database.
One table for example has a simple Primary-Key-ID column and a VARCHAR2 column.
The VARCHAR2 column has NO duplicate values, yet different unique IDs.
The PK column of this table is just referenced once as a foreign key in another table.
My thoughts are now to insert the values from the VARCHAR2 column into the the table which has held the primary key.
I could now remove the foreign key reference, delete the table and gain a new column with all the (duplicate) VARCHAR2 values. These I would like to compress in a unique/distinct way.
I have heard about index in the Oracle Database to compress column(s) but I am not quite sure which index I need or how to use them...
The underlying feature (and storage savings) should be about as the same as it was with the previous table of unique values and the foreign key reference.
Thank you for your help in advance!
Oracle basic compression allows us to compress tables. It comes with several distinct limitations, not the least of which is that it isn't suitable for OLTP databases. Direct path inserts, updates and deletes don't benefit. So you can't do what you want that way. If your organisation has sprung for the Advanced Compression licence then you have more options, but the compression still works on the table not an individual column.
I think you've confused things with index compression, which does operate on columns, as it allows us to compress the leading column(s) of a compound index. But it's worth applying only when there's a lot of repetition in those columns. If your index has a unique ID for the leading column than compression will actually increase the total amount of space taken. (Just one reason why compound indexes should be built with the least selective column first and the most selective column last.)
Your table is a classic key-value lookup table. So you could consider converting it into an index-organized table. You would save yourself a bit of space by maintaining only a specialized index instead of a table and its primary key index. Find out more

Data consistency between Oracle tables

I have one big table A who has PK (C1, C2, C3) and many other columns, to make the select faster, a smaller table B was created with PK (C1, C2). So we can do a select by joining the two tables to find a row in A.
But the problem now is that it can happen that if data is corrupted in B which results in a joint select returns nothing but we still have a row in A.
Am I doing something wrong with this design and how can I ensure the data in those two tables are consistent?
Thanks a lot.
Standard way - if those tables are in a master-detail relationship - is to create a foreign key constraint which will prevent deleting master if details exist.
If you can fix it now, do it - then create the constraint.
If you can't, then create foreign key constraint using INITIALLY DEFERRED DEFERRABLE option so that current values aren't checked, but future DML will be.
Finally, to fetch data although certain rows don't exist any more, use outer join.
"Am I doing something wrong with this design"
Well it's hard to be sure without more details about your scenario but probably you just needed a non-unique index on A(C1, C2).
Although I would like to see some benchmarking which proves an index-range scan on your primary key index was not up to the job. Especially as it seems likely the join on table B is using that access path.
Performance tuning an Oracle database is a matter of understanding and juggling many variables. It's not just a case of "bung on another index". We need to understand what the database is actually doing and why the optimiser made that choice. So, please read this post on asking Oracle tuning questions which will give you some insight into how to approach query optimisation.

Oracle SQL Data Modeler missing a PRIMARY KEY on DDL script export

The diagram has over 40 tables, most of them have a primary key defined.
For some reason there is this one table, which has a primary key defined, but that's being ignored when I export the model to a DDL script.
This is the "offending" key (even though it's checked it is nowhere to be found on the generated DDL script):
Has anybody had the same problem? Any ideas on how to solve it?
[EDIT] This is where the key is defined:
And this is the DDL preview (yes, the primary key shows up there):
This is what happens if I try to generate the DDL for just that table (primary key still not generated):
I was finally able to identify and reproduce the problem.
It was a simple conflict of constraints.
Table MIEMBROS had a mandatory 1 to n relationship (foreign key) from another table on its primary key column and vice-versa (there was a foreign key on MIEMBROS against the other table's primary key).
This kind of relationship between two tables makes it impossible to add a record to any of them: The insert operation will return an error complaining about the foreign key restriction pointing the other table.
Anyway I realized that one of the relationships was 0 to n so I simply unchecked the "mandatory" checkbox on the foreign key definition and everything went fine.
So, in a nutshell: The Data Modeler "fails" silently if you are defining a mutual relationship (two foreign keys, one on each table against the other table) on non nullable unique columns, by not generating the primary key of one of the tables.
Such an odd behavior, if you ask me!
"This kind of relationship between two tables makes it impossible to add a record to any of them: The insert operation will return an error complaining about the foreign key restriction pointing the other table."
Actually, if you have deferred constraints, this is not impossible. The constraints can be enforced, for example, at commit time rather than immediately at insert time.
From the Data Modeler menu under File, I used Export -> DDL File. The keys appeared in the DDL, then when I went back to the diagram and did DDL Preview, it showed all the missing stuff.

Is there any use to create index on all the table columns in oracle?

In our one of production database, we have 4 column table and there are no PK,UK constraints on it. only one notnull constraint on one column. The inserts are slow on this table and when I checked the indexes , there is one index which is built on all columns.
It is a normal table and not IOT. I really don't see a need of all column index, but wondering why the developers has created it?
Appreciate your thoughts?
It might be usefull, i.e. if you (mainly) query all columns oracle doesn't have to access the table at all, but can get all the data from the index. Though inserts take longer because a larger index has to be maintained by the dbms everytime.
One case where it could be useful is,
Say for example, you are trying to check the existence of records in this table and for that you have to have joins on all four columns. So in such a case if you have written a correlated query like below,
SELECT <something>
FROM table_1 t1
WHERE EXISTS
(SELECT 1 FROM table_t2 t2 where t1.c1=t2.c1 and t1.c2=t2.c2 and t1.c3=t2.c3 and t1.c4=t2.c4)
Apart from above case, it looks an error to me from developer's side.
Indexes are good to better query optimization but causes slow updates/inserts because the indexes needs to be updated at each modification.
If these tables first use is querying and inserts happens only in a specific periods like a batch at the beginning or the end of the day only, then you can remove the indexes before updating tables and then restore them.
In addition, all the queries all these tables need to be analysed to see which indexes are useful and which are not?
Anyway, You need to ask developers before removing these indexes.

Unindexed Foreign Key leads to TM Enqueue Contention

So we've been told that one source of TM Enq contention can be unindexed FK's. My question is which one.
I have an INSERT INTO Table_B that is recording TM Enq Wait.
It contains a PK that is the parent to other tables and it has columns that are FK constrained to other PKs.
So which FKs need indexed: that table's columns or its children?
NB: I know that this isn't the only cause of TM Contention. Can you explain why it couldn't possibly be this if that's the case.
Not sure about Oracle TM Contention, but I'd say normally both sides of a foreign key relation are indexed. Otherwise, the database will have to do table scans.
The index on the parent record is used whenever you insert a new child record, to verify that the parent exists. Often this is a primary key as well, so of course has an index.
The index on the child record is used whenever you change or delete a parent record, to perform cascades (including refusing the update/delete).
The indices on both sides also give the database a good chance of doing fast (indexed) joins, no matter which side its optimizer prefers to come from.
EDIT: Having Googled TM contention, it sounds like you're probably missing the keys on the child records. But make sure to have them on both sides, really.
EDIT 2: Answering the comment,
If you have a OLTP table that has 13 FKs to lookup tables, I'm not
keen on 13 index updates in addition to the table, pk and any other
indexes. An index is important but for specific reasons. If you never
update the parent PK nor delete from the parent, the child index is
not so useful. Or is it?
Depends on the joins and queries you're running, then. E.g., if you run
a query like:
SELECT o.something
FROM oltp_tab o JOIN lookup l ON (o.lookup_no = l.lookup_no)
WHERE l.lookup_name = ?
then the query optimizer would probably like the index on the child
records.
Also, according to http://ashmasters.com/waits/enq-tm-contention/ you
pretty much need to have the indices if you change the parent tables at
all. Apparently you get them from having concurrent changes to the
parent and child tables, unless you have the index. So this is probably
what you're seeing (assuming you're not doing the obvious things, like
updating the referred to columns or deleting rows)
The parent (referenced) column of an enabled foreign key relationship has to be indexed because it has to have an enabled unique or primary key constraint on it.
What mode of TM Enqueue are you seeing?

Resources