This is what awk was designed for:
$ awk -F'|' 'NR==FNR{c[$1$2]++;next};c[$1$2] > 0' file2 file1 abc|123|BNY|apple| cab|234|cyx|orange|
Explanation
-F'|' : sets the field separator to |. NR==FNR : NR is the current input line number and FNR the current file's line number. The two will be equal only while the 1st file is being read. c[$1$2]++; next : if this is the 1st file, save the 1st two fields in the c array. Then, skip to the next line so that this is only applied on the 1st file.
c[$1$2]>0 : the else block will only be executed if this is the second file so we check whether fields 1 and 2 of this file have already been seen (c[$1$2]>0) and if they have been, we print the line. In awk, the default action is to print the line so if c[$1$2]>0 is true, the line will be printed.
Alternatively, since you tagged with Perl:
perl -e 'open(A, "file2"); while(<A>){/.+?\|[^|]+/ && $k{$&}++}; while(<>){/.+?\|[^|]+/ && do{print if defined($k{$&})}}' file1
Explanation
The first line will open file2, read everything up to the 2nd | (.+?\|[^|]+) and save that (the $& is the result of the last match operator) in the %k hash.
The second line processes file1, uses the same regex to extract the 1st two columns and print the line if those columns are defined in the %k hash.
Both of the above approaches will need to hold the 2 first columns of file2 in memory. That shouldn't be a problem if you only have a few hundred thousand lines but if it is, you could do something like
cut -d'|' -f 1,2 file2 | while read pat; do grep "^$pat" file1; done
But that will be slower.
grep, it's under/usr/sfw/bin/ggrep. stackoverflow.com/questions/15259882/…