I've got a funny feeling both of the ignore_dupe_keys on the indexes is causing records to be spat out of the tables on insert:
Add a select above your insert and have a look at the values being returned:
SELECT place_id, data_id
FROM @rules r
INNER JOIN @data_table pp ON r.property_id = pp.property_id
ORDER BY place_id, r.property_id
INSERT INTO #tmp (place_id, data_id)
SELECT place_id, data_id
FROM @rules r
INNER JOIN @data_table pp ON r.property_id = pp.property_id
ORDER BY place_id, r.property_id
SELECT [place_id], [data_id]
FROM #tmp
I think what's happening is if a duplicate row is found both of the records are being spat from the tables as per the below. Weird hey!!!
/*
--can't have a duplicate place_id
--can't have a duplicate data_id
place_id, data_id
110 --No duplicate
120 --Duplicate place_id (spit the row from the @rules table, 2,3,4 left, also spit 20)
230 --No duplicate
240 --Duplicate place_id (spit the row from the @rules table, 3,4 left, also spit 40)
310 --Duplicate data_id (spit the row from the @rules table 4 left, also spit 10)
320 --(20 doesn't exist in the @data_table anymore so nothing to join on)
410 --Duplicate data_id (spit 4 from the @rules table. nothing left in the table.)
420 --table empty
430 --Duplicate data_id
440 --table empty
*/