First, thank you very much for taking the time to help.

The problem seems to be that Oracle knows how to do the join when it's just the select by itself. But when you add the insert statement, it goes and does something stupid with the select portion. I've inserted one of the versions of the query along with its explain plan below it.

insert /*+ APPEND */ into LDRWORKED
select /*+ INDEX(s SHIFTSFAC h TASKHISTORY_PK) */ s.SHIFTNUMBER, h.START_TIME, h.PROJECT_NUM, h.TASK_NUM
from SHIFTS s,
TASKHISTORY h
where s.FACILITYID = 'EA-N90-TRACON'
and h.FAC_IDENT = 'EA-N90-TRACON'
and s.EMPLOYEEID = h.EMPLOYEE_ID
and h.START_TIME between s.SHIFTSTART and s.SHIFTSTOP
and h.PROJECT_NUM is not null
and h.TASK_NUM is not null


Operation Object Name Rows Bytes Cost Object Node In/Out PStart PStop

INSERT STATEMENT Optimizer Mode=ALL_ROWS 7 K 5387
LOAD AS SELECT
HASH JOIN 7 K 729 K 5387
TABLE ACCESS BY INDEX ROWID SWARM.SHIFTS 30 K 1 M 517
INDEX RANGE SCAN SWARM.SHIFTSFAC 30 K 164
TABLE ACCESS FULL MSDT.DUTY_TBLTASK_HISTORY 45 K 2 M 4643