Das Problem ist doch, dass der Join als "Left join" definiert ist und per Where-Klausel ein Inner Join draus gemacht wird.

Und was heißt schon "alle Indizes"?

Du solltest den SQL etwas vereinfachen:

Select * from TEST01 WHERE

exists
(select * FROM HEADER
WHERE TEST01.LAUFNUMMER = HEADER.LAUFNUMMER
and HEADER.TIMESTAMP > '2019-07-08 00:00:00' AND HEADER.TIMESTAMP < '2019-07-15 00:00:00' )

OR exists
(select * FROM DATEI02
WHERE TEST01.LAUFNUMMER = DATEI02.PK
and DATEI02.TIMESTAMP > '2019-07-17 00:00:00' AND DATEI02.TIMESTAMP < '2019-07-24
00:00:00')

Zusätzlich benütigst du einen Index jeweils über "LAUFNUMMER/PK, TIMESTAMP".

Ein "in (Select ...)" baut i.d.R. erst eine Liste aller Werte auf, die dann sequentiell durchsucht wird.
Im Zweifel sogar pro Satz der 1. From-Klausel, was die extreme Laufzeit erklärt.
Du willst aber nur wissen, ob überhaupt etwas vorkommt.
Der "exists" sucht hier aber über Index-Only-Access, da ja die Daten gar nicht benötigt werden und hört beim 1. Vorkommen bereits auf.