1

I have a table with some 7M rows and an SSIS package that updates 5.6M rows in that table with a statement like the following.

MERGE INTO Target t
USING
(
 select ID,
 Type
 from SomeTable
) s
ON (t.ID = s.ID)
WHEN MATCHED THEN UPDATE SET t.Type = s.Type

I then start several large select statements that do an inner join to Target. I've been getting ORA-01555 (snapshot too old: rollback segment number string with name "string" too small) from those select statements. This looks to me like the MERGE statement returns before the commit has finished. My initial thought was to increase the size of the rollback segment (which admittedly might introduce integrity problems) but our DBAs were not keen on that idea. They suggested I wait for 1 minute before starting the select statements. (To me synchronization with artificial waits is a red flag.)

My question is, is there any way to ensure that the MERGE commit has finished before the MERGE statement returns? To me that would solve the problem.

Rubio
  • 1,067
  • 1
  • 14
  • 25
  • 1
    If you want to commit, issue a commit. – Mat Jun 14 '18 at 07:22
  • 1
    A merge (or any other DML statement) doesn't commit. You either need to explicitly commit after it completes; or be using a client/driver set to autocommit, which will still happen after the merge completes. So how are you running the merge and the subsequent queries? Are the queries perhaps in a different session and are trying to look at the pre-merge data, because it hasn't been committed at all yet? – Alex Poole Jun 14 '18 at 08:02
  • Can you post your SQL with inner joins. Are you calling them in the loop? Recommendation from DBAs sounds odd to me. And Merge does not commit. – Rusty Jun 14 '18 at 08:03
  • http://www.orafaq.com/wiki/ORA-01555 – William Robertson Jun 14 '18 at 08:06
  • @AlexPoole I've been wondering about the commit. My SSIS package uses the Oracle OLEDB provider so if I don't explicitly commit then there must be something under the covers that does the commit. The merge is an SSIS Execute SQL Task and the selects are SSIS Data Flows using Attunity Oracle Source component. – Rubio Jun 14 '18 at 08:07

1 Answers1

1

I would avoid merging entire tables (if possible):

MERGE INTO Target t
USING( select ID, Type
      from SomeTable
      where some_kind_of_timestamp_column > date_of_last_incremental_load
) s
ON (t.ID = s.ID)
WHEN MATCHED THEN UPDATE SET t.Type = s.Type
                  WHERE (t.Type != s.Type)
                    OR (t.Type IS NULL AND s.TYPE IS NOT NULL)
                    OR (t.Type IS NOT NULL AND s.TYPE IS NULL)
                  -- there is no need for updating A -> A

COMMIT;

-- some select
Lukasz Szozda
  • 162,964
  • 23
  • 234
  • 275
  • I was wondering about that. Is there an implicit commit or does the OLDB provider insert a commit? But if the solution is as simple as that then great. – Rubio Jun 14 '18 at 08:02
  • Also, I happen to know that t.Type is null at this point. That's why I don't have the where clause in the update. – Rubio Jun 14 '18 at 09:37
  • @Rubio `Also, I happen to know that t.Type is null at this point. That's why I don't have the where clause in the update` That is poor explanation. If you have more than one column in `UPDATE` there is [`IS DISTINCT FROM`](https://stackoverflow.com/a/50280408/5070879) solution – Lukasz Szozda Jun 14 '18 at 09:37
  • Not sure what you mean by 'poor explanation'. If I had more than one column to update, I would deal with it, but I don't. Does my solution present possible problems, integrity, performance? – Rubio Jun 14 '18 at 09:47
  • 1
    @Rubio Yes, unnecessary updates. There is no point of updating all matching rows and generating a lot of undo/redo. – Lukasz Szozda Jun 14 '18 at 09:49
  • Oh I see. Again, I happen to know that ID is the PK on both tables so no chance of unnecessary updates. Also, I found no mention of `IS DISTINCT FROM` in Oracle 12.1 docs. May not be supported. Thanks for pointing that out, though. – Rubio Jun 14 '18 at 09:54
  • @Rubio By `IS DISTINCT FROM` I meant more about concept (not actual syntax - you could easily emulate it with `NOT EXISTS - INTERSECT/EXISTS-MINUS` keywords. – Lukasz Szozda Jun 14 '18 at 09:56
  • @Rubio I suggest to open SQL Developer and check MERGE + WHERE from there. Academic discussion won't substitute hands on experience. – Lukasz Szozda Jun 14 '18 at 10:03